This repository has been archived by the owner on Feb 19, 2022. It is now read-only.
/
PausableMovie.jsx
53 lines (46 loc) · 1.63 KB
/
PausableMovie.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import classNames from 'classnames';
import React from 'react';
import { AspectRatioBox } from '../AspectRatioBox';
import { FontAwesomeIcon } from '../FontAwesomeIcon';
/**
* @typedef {object} Props
* @property {string} src
*/
/**
* クリックすると再生・一時停止を切り替えます。
* @type {React.VFC<Props>}
*/
const PausableMovie = ({ src }) => {
/** @type {React.RefObject<HTMLVideoElement>} */
const videoRef = React.useRef(null);
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const [isPlaying, setIsPlaying] = React.useState(!prefersReducedMotion);
const handleClick = React.useCallback(() => {
setIsPlaying((isPlaying) => {
if (isPlaying) {
videoRef.current?.pause();
} else {
videoRef.current?.play();
}
return !isPlaying;
});
}, []);
return (
<AspectRatioBox aspectHeight={1} aspectWidth={1}>
<button className="group relative block w-full h-full" onClick={handleClick} type="button">
<video src={src} ref={videoRef} className="w-full" muted autoPlay={!prefersReducedMotion} loop />
<div
className={classNames(
'absolute left-1/2 top-1/2 flex items-center justify-center w-16 h-16 text-white text-3xl bg-black bg-opacity-50 rounded-full transform -translate-x-1/2 -translate-y-1/2',
{
'opacity-0 group-hover:opacity-100': isPlaying,
},
)}
>
<FontAwesomeIcon iconType={isPlaying ? 'pause' : 'play'} styleType="solid" />
</div>
</button>
</AspectRatioBox>
);
};
export { PausableMovie };