mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-10 12:01:36 +00:00
scrubbing works completely when playing video
This commit is contained in:
1 parent
2f563409cb
commit
758a50f9ee
3 files changed
+50
-25
No files matched your search
+24
-4
@@ -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}
|
||||
|
||||
+21
-17
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user