ScottSpence.com

Scott's Digital Garden.

🤫This is a private post👀

Create a Video Overlay with Hooks

Create a Video overlay with React hooks

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}

Back to Top