scrubbing works completely when playing video

This commit is contained in:
wil committed 2024-03-17 16:42:24 -04:00
1 parent 2f563409cb
commit 758a50f9ee
3 files changed
+50 -25

No files matched your search

@@ -1,13 +1,14 @@
import React, {
useContext,
useCallback,
useState,
useContext,
useEffect,
useLayoutEffect,
useState,
useRef,
} from 'react';
import { withScrubbing, withScrubbingPropsI } from './withScrubbing';
import { VideoElementContext } from '../../contexts';
import { withScrubbing, withScrubbingPropsI } from './withScrubbing';
interface TimeCursorPropsI {
debug?: boolean
@@ -23,6 +24,8 @@ export const TimeCursor = ({
const videoElement = useContext(VideoElementContext);
const [timeCursorOffset, setTimeCursorOffset] = useState(0);
const [boundingWidth, setBoundingWidth] = useState(videoElement?.getBoundingClientRect().width || 0);
const isLockedForScrubbing = useRef<boolean>(false);
const wasPlaying = useRef<boolean>(false);
const PlayCursorWithScrubbing = withScrubbing<withScrubbingPropsI>(()=>{
return(
@@ -31,7 +34,7 @@ export const TimeCursor = ({
});
useEffect(()=>{
const handleTimeCursorPosition = ()=>{
if(videoElement!==null){
if(videoElement!==null && !isLockedForScrubbing.current){
const newOffset = (videoElement.currentTime / videoElement.duration) * (boundingWidth);
setTimeCursorOffset(newOffset);
@@ -57,17 +60,34 @@ export const TimeCursor = ({
};
}, [handleWindowResize])
const handleOnScrubStart = () => {
isLockedForScrubbing.current = true;
if(videoElement!==null) {
if (videoElement.paused) wasPlaying.current = false;
else {
wasPlaying.current = true;
videoElement.pause();
}
}
}
const handleOnScrubEnd = useCallback( (newPos: number)=>{
isLockedForScrubbing.current = false;
if(videoElement !== null){
const newTime = newPos / boundingWidth * videoElement.duration;
videoElement.currentTime = newTime;
if(wasPlaying.current === true){
videoElement.play();
}
}
},[videoElement, boundingWidth]);
return(
<PlayCursorWithScrubbing
boundingWidth={boundingWidth}
hitboxPadding={16}
scrubberWidth={8}
onScrubStart={handleOnScrubStart}
onScrubEnd={handleOnScrubEnd}
scrubPosition={timeCursorOffset}
{...rest}
@@ -10,6 +10,7 @@ export interface withScrubbingPropsI {
debug?: boolean
boundingWidth: number;
scrubberWidth: number;
hitboxPadding?: number;
scrubPosition?: number; // scrubber location as px
styleOverride?: {[key: string]: string|number };
onScrubStart?: ()=>void;
@@ -28,19 +29,20 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
debug: propsDebug = false,
boundingWidth,
scrubberWidth,
hitboxPadding = 0,
scrubPosition: propsLeftOffset = 0,
styleOverride = {},
onScrubStart,
onScrubEnd,
...rest
}: withScrubbingPropsI) => {
// const debug = false || propsDebug;
const debug = true || propsDebug;
const refEl = useRef<HTMLDivElement| null>(null);
// const refListener = useRef<number>(Date.now());
const refListener = useRef<number>(Date.now());
// if (debug) console.log(`${refListener.current} withSCRUBBING reRENDERING!! `);
if (debug) console.log(`${refListener.current} withSCRUBBING reRENDERING!! `);
const [{
currLeftOffset, pointerStartPos,
@@ -53,8 +55,8 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
useLayoutEffect(() => {
// if (debug) console.log(`withSCRUBBING useLAYOUTeffect!! `);
function handleScrubStart (e: MouseEvent) {
// if (debug) console.log(`${refListener.current} withSCRUBBING SCRUB_START!! `);
function handleScrubStart (e: PointerEvent) {
if (debug) console.log(`${refListener.current} withSCRUBBING SCRUB_START!! `);
e.preventDefault();
e.stopPropagation();
if(refEl.current){
@@ -63,14 +65,15 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
...curr,
pointerStartPos: e.clientX
}));
if(onScrubStart) onScrubStart();
window.addEventListener("pointermove", handleScrubMove);
return true;
}
}
};
function handleScrubEnd (e: MouseEvent){
// if (debug) console.log(`${refListener.current} withSCRUBBING SCRUB_END!! `);
function handleScrubEnd (e: PointerEvent){
if (debug) console.log(`${refListener.current} withSCRUBBING SCRUB_END!! `);
e.preventDefault();
e.stopPropagation();
@@ -82,8 +85,8 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
setBySelf: Date.now(),
}));
};
function handleScrubMove (e: MouseEvent){
// if (debug) console.log(`${refListener.current} withSCRUBBING SCRUB_MOVE!! `);
function handleScrubMove (e: PointerEvent){
if (debug) console.log(`${refListener.current} withSCRUBBING SCRUB_MOVE!! `);
e.preventDefault();
e.stopPropagation();
@@ -119,12 +122,12 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
// }
}, [scrubberWidth, boundingWidth]);
useEffect(()=>{
// if (debug) console.log(`${refListener.current} withSCRUBBING useEFFECT for scrubStart!! `);
if(onScrubStart && pointerStartPos > 0){
onScrubStart();
}
},[pointerStartPos, onScrubStart]);
// useEffect(()=>{
// // if (debug) console.log(`${refListener.current} withSCRUBBING useEFFECT for scrubStart!! `);
// if(onScrubStart && pointerStartPos > 0){
// onScrubStart();
// }
// },[pointerStartPos, onScrubStart]);
useEffect(()=>{
// if (debug) console.log(`${refListener.current} withSCRUBBING useEFFECT for scrubEend!! `);
@@ -159,7 +162,8 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
position: 'absolute',
top:0,
width: scrubberWidth + 'px',
left: currLeftOffset + 'px',
padding: hitboxPadding + 'px',
left: (currLeftOffset - hitboxPadding) + 'px',
cursor: pointerStartPos >=0 ? 'grabbing': 'grab',
...styleOverride
}}
@@ -105,10 +105,10 @@ $scrubber-bar-height: 2rem;
}
.with-scrubber-wrapper{
box-shadow: 1px 1px 4px 0px rgba(0,0,0,1);
// transition: 0.5s;
}
// .with-scrubber-wrapper{
// // transition: 0.5s;
// }
.trim-scrubber{
height: 3rem;
background-color: #e66462;
@@ -116,6 +116,7 @@ $scrubber-bar-height: 2rem;
outline: 0.125rem $white solid;
border-top: 1rem $white solid;
border-radius: 0.25rem 0.25rem 0.125rem 0.125rem;
display: flex;