playbar responsiveness and perfect offset math

This commit is contained in:
wil committed 2024-02-27 17:44:42 -05:00
1 parent 02f6d86390
commit ed7e5ee808
2 files changed
+70 -29

No files matched your search

@@ -1,5 +1,6 @@
import React, {
useCallback,
useLayoutEffect,
useState,
useRef,
PointerEvent
@@ -31,8 +32,13 @@ function formatSecondsToHHMMSS(seconds:number){
else
return new Date(seconds * 1000).toISOString().slice(11, 19);
}
export type QuickTrimType = {
trimStartSeconds: number;
trimEndSecondds: number;
}
interface VideoQuickTrimProps extends VideoFakeyouProps{
onChange: ()=>void;
onSelect: (val: QuickTrimType)=>void;
}
type TrimState = {
@@ -42,38 +48,28 @@ type TrimState = {
trimEnd: number;
maxDuration: number;
}
const initialState = {
const initialTrimState = {
isScrubbingTrim: false,
trimDuration: 3,
trimStart: 0,
trimEnd: 0,
maxDuration: 0,
}
type PlaybarState = {
playbarWidth: number;
timeCursorOffset: number;
}
const initialPlaybarState = {
playbarWidth: 0,
timeCursorOffset: 0,
}
export default function VideoQuickTrim({
onChange,
onSelect,
...rest
}: VideoQuickTrimProps){
console.log("Rerender!!");
const videoRef = useRef<HTMLVideoElement | null>(null);
const [currentTimePortion, setCurretTimePortion] = useState<number>(0);
const videoRefCallback = useCallback(node => {
if (node !== null) {
// DOM node referenced by ref has changed and exists
videoRef.current = node;
node.ontimeupdate = (e: PointerEvent)=>{
console.log(`${node.currentTime}/${node.duration} ${node.currentTime / node.duration}`);
setCurretTimePortion(
fractionToPercentage(node.currentTime / node.duration)
);
}
} else {
// DOM node referenced by ref has been unmounted
}
}, []); //END videoRefCallback
const trimOptions: { [key: string]: number } = {
"3s": 3,
"5s": 5,
@@ -81,13 +77,57 @@ export default function VideoQuickTrim({
"15s" : 15,
"20s" : 20,
};
const videoRef = useRef<HTMLVideoElement | null>(null);
const playbarRef = useRef<HTMLDivElement | null>(null);
const trimZoneRef = useRef<HTMLDivElement>(null);
const playbarRef = useRef<HTMLDivElement>(null);
const [{playbarWidth, timeCursorOffset}, setPlaybarState] = useState<PlaybarState>(initialPlaybarState);
const [playpause, setPlaypause] = useState<'playing'|'paused'|'stopped'>('paused');
const [{
trimDuration,
isScrubbingTrim,
}, setState] = useState<TrimState>(initialState);
}, setState] = useState<TrimState>(initialTrimState);
const videoRefCallback = useCallback(node => {
if (node !== null) {
// DOM node referenced by ref has changed and exists
videoRef.current = node;
node.ontimeupdate = (e: PointerEvent)=>{
setPlaybarState((curr)=>({
...curr,
timeCursorOffset: (node.currentTime / node.duration) * (playbarWidth-8)
}));
}
} // else{} DOM node referenced by ref has been unmounted
}, [playbarWidth]); //END videoRefCallback
function handleWindowResize() {
if(playbarRef.current !== null){
const newWidth = playbarRef.current.getBoundingClientRect().width;
setPlaybarState((curr)=>({
playbarWidth: newWidth,
timeCursorOffset: (curr.timeCursorOffset / (curr.playbarWidth-8)) * (newWidth-8)
}));
}
}
const playbarRefCallback = useCallback(node => {
if(node !== null) {
playbarRef.current = node;
setPlaybarState((curr)=>({
...curr,
playbarWidth: node.getBoundingClientRect().width
}));
}
}, []);
useLayoutEffect(()=>{
window.addEventListener('resize', handleWindowResize);
return () => {
window.removeEventListener('resize', handleWindowResize);
};
},[]);
const handleChangeTrimDuration = (selected: string) =>{
setState((curr)=>({
@@ -127,7 +167,7 @@ export default function VideoQuickTrim({
</div>
</div>{/* END of Video Wrapper */}
<div className="playbar" ref={playbarRef}>
<div className="playbar" ref={playbarRefCallback}>
<div className="playbar-bg" />
<div className="trimzone"
ref={trimZoneRef}
@@ -150,7 +190,7 @@ export default function VideoQuickTrim({
trimZoneRef.current.style.cursor = 'grab';
setState((curr)=>({
...curr,
isScrubbingTrim: true,
isScrubbingTrim: false,
}));
}
}}
@@ -164,7 +204,7 @@ export default function VideoQuickTrim({
>
<FontAwesomeIcon icon={faGripDots} />
</div>
<div className="playcursor" style={{left: currentTimePortion+"%"}}/>
<div className="playcursor" style={{left: timeCursorOffset+"px"}}/>
</div> {/* END of Playbar */}
<div className="d-flex w-100 justify-content-between mt-3 flex-wrap">
@@ -7,8 +7,9 @@ import {Container, Panel} from 'components/common';
export default function ComponentSandbox(
{parentPath}:{parentPath:string}
){
const onChange = ()=>{
const handleCallback = (val:any)=>{
console.log('onChange is triggered')
console.log(val);
}
return (<Container>
<NavLink to={`${parentPath}`}>← Back</NavLink>
@@ -17,7 +18,7 @@ export default function ComponentSandbox(
<div className="m-4">
<VideoQuickTrim
onChange={onChange}
onSelect={handleCallback}
mediaToken='m_wdptbe5rfzpb1gzhva78gpw8qrkgs9'
/>
</div>
@@ -25,7 +26,7 @@ export default function ComponentSandbox(
<br/>
<div className="m-4">
<VideoQuickTrim
onChange={onChange}
onSelect={handleCallback}
mediaToken='m_h21nykes0j3ph23y5z7w9axtjjn2rr'
/>
</div>