6 changed files with 124 additions and 28 deletions
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
import { BackdropControl } from "./controls/BackdropControl"; |
||||
import { FullscreenControl } from "./controls/FullscreenControl"; |
||||
import { LoadingControl } from "./controls/LoadingControl"; |
||||
import { PauseControl } from "./controls/PauseControl"; |
||||
import { ProgressControl } from "./controls/ProgressControl"; |
||||
import { TimeControl } from "./controls/TimeControl"; |
||||
import { VolumeControl } from "./controls/VolumeControl"; |
||||
import { VideoPlayer, VideoPlayerProps } from "./VideoPlayer"; |
||||
|
||||
export function DecoratedVideoPlayer(props: VideoPlayerProps) { |
||||
return ( |
||||
<VideoPlayer autoPlay={props.autoPlay}> |
||||
<BackdropControl> |
||||
<PauseControl /> |
||||
<FullscreenControl /> |
||||
<ProgressControl /> |
||||
<VolumeControl /> |
||||
<LoadingControl /> |
||||
<TimeControl /> |
||||
</BackdropControl> |
||||
{props.children} |
||||
</VideoPlayer> |
||||
); |
||||
} |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
import { useCallback, useRef, useState } from "react"; |
||||
import { useVideoPlayerState } from "../VideoContext"; |
||||
|
||||
interface BackdropControlProps { |
||||
children?: React.ReactNode; |
||||
} |
||||
|
||||
export function BackdropControl(props: BackdropControlProps) { |
||||
const { videoState } = useVideoPlayerState(); |
||||
const [moved, setMoved] = useState(false); |
||||
const timeout = useRef<ReturnType<typeof setTimeout> | null>(null); |
||||
|
||||
const handleMouseMove = useCallback(() => { |
||||
setMoved(true); |
||||
if (timeout.current) clearTimeout(timeout.current); |
||||
timeout.current = setTimeout(() => { |
||||
setMoved(false); |
||||
timeout.current = null; |
||||
}, 3000); |
||||
}, [timeout, setMoved]); |
||||
|
||||
const handleClick = useCallback(() => { |
||||
if (videoState.isPlaying) videoState.pause(); |
||||
else videoState.play(); |
||||
}, [videoState]); |
||||
|
||||
const showUI = moved || videoState.isPaused; |
||||
|
||||
return ( |
||||
<div |
||||
className={`absolute inset-0 ${!showUI ? "cursor-none" : ""}`} |
||||
onMouseMove={handleMouseMove} |
||||
onClick={handleClick} |
||||
> |
||||
<div |
||||
className={`absolute inset-0 bg-black bg-opacity-20 transition-opacity duration-200 ${ |
||||
!showUI ? "!opacity-0" : "" |
||||
}`}
|
||||
/> |
||||
<div |
||||
className={`absolute inset-x-0 bottom-0 h-[30%] bg-gradient-to-t from-black to-transparent opacity-75 transition-opacity duration-200 ${ |
||||
!showUI ? "!opacity-0" : "" |
||||
}`}
|
||||
/> |
||||
<div |
||||
className={`absolute inset-x-0 top-0 h-[30%] bg-gradient-to-b from-black to-transparent opacity-75 transition-opacity duration-200 ${ |
||||
!showUI ? "!opacity-0" : "" |
||||
}`}
|
||||
/> |
||||
<div className="absolute inset-0">{showUI ? props.children : null}</div> |
||||
</div> |
||||
); |
||||
} |
Loading…
Reference in new issue