Create a Video Overlay with Hooks
Hey! Thanks for stopping by! Just a word of warning, this post
is 6 years old, wow! If there's technical information in here it's more than likely out
of date.
Create a Video overlay with React hooks.
I had to create a video overlay for a project I was working on. This
example use a portal to render the player with react-player.
1// useModal.js
2import { useState } from 'react';
3
4export const useModal = () => {
5 const [isShowing, setIsShowing] = useState(false);
6
7 const toggle = () => {
8 setIsShowing(!isShowing);
9 };
10
11 return {
12 isShowing,
13 toggle,
14 };
15};1// VideoPlayer.js
2import React from 'react';
3import ReactPlayer from 'react-player';
4
5export const VideoPlayer = (props) => {
6 return (
7 <ReactPlayer
8 {...props}
9 url="https://www.youtube.com/watch?reload=9&v=YE7VzlLtp-4"
10 playing={props.playing}
11 controls
12 width="100%"
13 height="100%"
14 css={{
15 position: `absolute`,
16 top: 0,
17 left: 0,
18 }}
19 />
20 );
21};1// VideoModal.js
2import React from 'react';
3import ReactDOM from 'react-dom';
4import styled from 'styled-components';
5import closePrimary from '../../static/buttonClose.svg';
6import { VideoPlayer } from './VideoPlayer';
7
8const ModalOverlay = styled.div`
9 position: fixed;
10 top: 0;
11 left: 0;
12 width: 100vw;
13 height: 100vh;
14 background-color: darkgrey;
15 opacity: 0.5;
16`;
17
18const ModalWrapper = styled.div`
19 position: fixed;
20 top: 0;
21 left: 0;
22 outline: 0;
23 position: fixed;
24 top: 10vh;
25 bottom: 10vh;
26 left: 10vh;
27 right: 10vh;
28 display: flex;
29`;
30
31const ModalHeader = styled.div`
32 position: fixed;
33 top: 20px;
34 right: 20px;
35 padding: 1.5rem;
36 z-index: 1;
37`;
38
39const Modal = styled.div`
40 background: ${({ theme }) => theme.primary};
41 position: relative;
42 border-radius: 3px;
43 display: flex;
44 flex-direction: column;
45 flex: 1;
46`;
47
48const CloseButton = styled.div`
49 padding: 30px;
50 border-radius: 50%;
51 margin: -1rem -1rem -1rem auto;
52 cursor: pointer;
53 background-repeat: no-repeat;
54 background-image: url(${closePrimary});
55`;
56
57const PlayerWrapper = styled.div`
58 position: relative;
59 flex: 1;
60 padding: 50px 0;
61`;
62
63const PlayerSizer = styled.div`
64 width: 0;
65 height: 100%;
66 padding-right: 82%;
67 margin: 0 auto;
68`;
69
70export const VideoModal = ({ isShowing, hide }) =>
71 isShowing
72 ? ReactDOM.createPortal(
73 <>
74 <ModalOverlay onClick={hide} />
75 <ModalWrapper
76 aria-modal
77 aria-hidden
78 tabIndex={-1}
79 role="dialog"
80 >
81 <Modal>
82 <ModalHeader>
83 <CloseButton
84 data-dismiss="modal"
85 aria-label="Close"
86 onClick={hide}
87 />
88 </ModalHeader>
89 <PlayerWrapper>
90 <PlayerSizer>
91 <VideoPlayer playing={true} />
92 </PlayerSizer>
93 </PlayerWrapper>
94 </Modal>
95 </ModalWrapper>
96 </>,
97 document.body,
98 )
99 : null;Then in the component:
1import React from 'react';
2import { VideoModal } from '../components/VideoModal';
3import { useModal } from '../hooks/useModal';
4import styled from 'styled-components';
5import playSvg from '../../static/playIcon.svg';
6
7const Wrapper = styled.div`
8 height: 100%;
9 display: flex;
10 align-items: center;
11 justify-content: center;
12`;
13
14const PlayDiv = styled.div`
15 /* margin: 0 auto; */
16 background-repeat: no-repeat;
17 height: 50px;
18 width: 50px;
19 background-image: url(${playSvg});
20`;
21
22export default () => {
23 const { isShowing, toggle } = useModal();
24 return (
25 <>
26 <Wrapper>
27 <VideoModal isShowing={isShowing} hide={toggle} />
28 {/* <button onClick={toggle}>Click This Button</button> */}
29 <PlayDiv onClick={toggle} />
30 </Wrapper>
31 </>
32 );
33};There's a reactions leaderboard you can check out too.
Sign up for the newsletter
Want to keep up to date with what I'm working on?
Join other developers and sign up for the newsletter.
I care about the protection of your data. Read the Privacy Policy for more info.