mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-06 18:21:12 +00:00
double scrubbing player, both trim and playcursor can be scrubbed
This commit is contained in:
1 parent
f4e4838259
commit
01a5d5dcd7
5 files changed
+78
-52
No files matched your search
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { withScrubbing, withScrubbingPropsI } from './withScrubbing';
|
||||
|
||||
interface PlayCursorPropsI extends withScrubbingPropsI{
|
||||
// timeCursorOffset: number;
|
||||
onChanged: (posPercent: number)=>void;
|
||||
|
||||
}
|
||||
|
||||
export const PlayCursor = ({
|
||||
// timeCursorOffset,
|
||||
onChanged,
|
||||
...rest
|
||||
}:PlayCursorPropsI)=>{
|
||||
const PlayCursorWithScrubbing = withScrubbing<withScrubbingPropsI>(()=>{
|
||||
return(
|
||||
<div className="playcursor" />
|
||||
);
|
||||
});
|
||||
|
||||
return(
|
||||
<PlayCursorWithScrubbing
|
||||
onScrubChanged={onChanged}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
+11
-13
@@ -8,13 +8,12 @@ import {
|
||||
Action,
|
||||
ACTION_TYPES,
|
||||
} from '../reducer';
|
||||
import { QuickTrimData } from '../utilities';
|
||||
import { TrimScrubber } from './TrimScrubber';
|
||||
import { PlayCursor } from './PlayCursor';
|
||||
|
||||
export const ProgressBar = memo(({
|
||||
readyToMount,
|
||||
timeCursorOffset,
|
||||
// trimReset,
|
||||
trimStartSeconds,
|
||||
trimDuration,
|
||||
playbarWidth,
|
||||
@@ -24,7 +23,6 @@ export const ProgressBar = memo(({
|
||||
}:{
|
||||
readyToMount: boolean;
|
||||
timeCursorOffset: number;
|
||||
// trimReset: number;
|
||||
trimStartSeconds: number;
|
||||
trimDuration: number;
|
||||
playbarWidth: number;
|
||||
@@ -71,28 +69,28 @@ export const ProgressBar = memo(({
|
||||
<div className="playbar" ref={playbarRefCallback}>
|
||||
<div className="playbar-bg" />
|
||||
<TrimScrubber
|
||||
// key={trimReset}
|
||||
boundingWidth={playbarWidth}
|
||||
scrubberWidth={scrubberWidth}
|
||||
trimStartSeconds={trimStartSeconds}
|
||||
trimDuration={trimDuration}
|
||||
videoDuration={videoDuration}
|
||||
onChange={(val: QuickTrimData)=>{
|
||||
|
||||
onChange={(newPos: number)=>{
|
||||
const newTrimStartSeconds = newPos / (playbarWidth - scrubberWidth) * videoDuration;
|
||||
dispatchCompState({
|
||||
type: ACTION_TYPES.MOVE_TRIM,
|
||||
payload: {
|
||||
trimStartSeconds: val.trimStartSeconds,
|
||||
trimEndSeconds: val.trimEndSeconds
|
||||
trimStartSeconds: newTrimStartSeconds,
|
||||
trimEndSeconds: newTrimStartSeconds + trimDuration
|
||||
}
|
||||
});
|
||||
// onSelect({
|
||||
// trimStartSeconds: val.trimStartSeconds,
|
||||
// trimEndSeconds: val.trimEndSeconds,
|
||||
// });
|
||||
}}
|
||||
/>
|
||||
<div className="playcursor" style={{left:timeCursorOffset+"px"}}/>
|
||||
<PlayCursor
|
||||
scrubPosition={timeCursorOffset}
|
||||
onChanged={(onChangedVal)=>{console.log(onChangedVal)}}
|
||||
boundingWidth={playbarWidth}
|
||||
scrubberWidth={8}
|
||||
/>
|
||||
{/* END of Playbar */}</div>
|
||||
);
|
||||
}else{
|
||||
|
||||
+6
-15
@@ -1,19 +1,18 @@
|
||||
import React, {
|
||||
memo,
|
||||
useCallback
|
||||
} from 'react';
|
||||
import {
|
||||
faGripDots
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { QuickTrimData } from '../utilities';
|
||||
import {withScrubbing, withScrubbingPropsI} from './withScrubbing';
|
||||
import { withScrubbing, withScrubbingPropsI } from './withScrubbing';
|
||||
|
||||
interface TrimScrubberPropsI extends withScrubbingPropsI {
|
||||
trimStartSeconds:number;
|
||||
trimDuration: number;
|
||||
videoDuration: number;
|
||||
onChange:(val:QuickTrimData)=>void
|
||||
// onChange:(val:QuickTrimData)=>void
|
||||
onChange:(newPos:number)=>void
|
||||
}
|
||||
export const TrimScrubber = memo(({
|
||||
trimStartSeconds,
|
||||
@@ -30,23 +29,15 @@ export const TrimScrubber = memo(({
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const handleOnChange = useCallback((posPercent:number)=>{
|
||||
console.log(`handle on moving trim scrubber, pos%=${posPercent}`);
|
||||
onChange({
|
||||
trimStartSeconds: videoDuration * posPercent,
|
||||
trimEndSeconds: videoDuration * posPercent + trimDuration,
|
||||
});
|
||||
}, [onChange, videoDuration, trimDuration]);
|
||||
|
||||
return (
|
||||
<TrimScrubberWithScrubbing
|
||||
styleOverride={{
|
||||
top: '-1rem',
|
||||
}}
|
||||
initialLeftOffsetPercent={trimStartSeconds/videoDuration}
|
||||
onScrubChanged={handleOnChange}
|
||||
scrubPosition={trimStartSeconds/videoDuration*(rest.boundingWidth-rest.scrubberWidth)}
|
||||
onScrubChanged={onChange}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
);
|
||||
});
|
||||
+32
-23
@@ -4,31 +4,29 @@ import React,{
|
||||
useRef,
|
||||
useState,
|
||||
useLayoutEffect,
|
||||
// useCallback,
|
||||
} from 'react';
|
||||
|
||||
export interface withScrubbingPropsI {
|
||||
boundingWidth: number;
|
||||
scrubberWidth: number;
|
||||
initialLeftOffset?: number; //in pixels
|
||||
initialLeftOffsetPercent?: number; // in %, 0 < % < 1
|
||||
scrubPosition?: number;
|
||||
// scrubber location as px
|
||||
styleOverride?: {[key: string]: string|number };
|
||||
onScrubChanged?: (posPercent: number)=>void;
|
||||
//return scrubber location as %, where 0 < % < 1
|
||||
onScrubChanged?: (newPos: number)=>void;
|
||||
//return scrubber location as px
|
||||
}
|
||||
|
||||
type withSrcubbingStates = {
|
||||
key: number,
|
||||
currLeftOffset: number,
|
||||
prevLeftOffset: number;
|
||||
prevPropsLeftOffset: number;
|
||||
pointerStartPos: number;
|
||||
}
|
||||
|
||||
export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.ComponentType<P>) => memo(({
|
||||
boundingWidth,
|
||||
scrubberWidth,
|
||||
initialLeftOffset : initialLeftOffsetProps = 0,
|
||||
initialLeftOffsetPercent = 0,
|
||||
scrubPosition: propsLeftOffset = 0,
|
||||
styleOverride = {},
|
||||
onScrubChanged,
|
||||
...rest
|
||||
@@ -37,18 +35,14 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
|
||||
const refEl = useRef<HTMLDivElement| null>(null);
|
||||
const refListener = useRef<number>(Date.now());
|
||||
|
||||
const initialLeftOffset =
|
||||
initialLeftOffsetPercent > 0 ? boundingWidth * initialLeftOffsetPercent
|
||||
: initialLeftOffsetProps;
|
||||
|
||||
const [{
|
||||
// key,
|
||||
currLeftOffset, pointerStartPos,
|
||||
prevLeftOffset,
|
||||
prevLeftOffset
|
||||
}, setStates] = useState<withSrcubbingStates>({
|
||||
key: Date.now(),
|
||||
currLeftOffset: initialLeftOffset, // in pixels
|
||||
prevLeftOffset: initialLeftOffset, //in pixels
|
||||
currLeftOffset: propsLeftOffset,
|
||||
prevLeftOffset: propsLeftOffset,
|
||||
prevPropsLeftOffset: propsLeftOffset,
|
||||
pointerStartPos: -1 // negative denotes pointer not engaged
|
||||
});
|
||||
|
||||
@@ -72,6 +66,7 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
|
||||
...curr,
|
||||
pointerStartPos: -1,
|
||||
prevLeftOffset: curr.currLeftOffset,
|
||||
setBySelf: Date.now(),
|
||||
}));
|
||||
};
|
||||
function handleScrubMove (e: MouseEvent){
|
||||
@@ -88,7 +83,7 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
|
||||
if(newLeftOffset !== curr.currLeftOffset){
|
||||
return{
|
||||
...curr,
|
||||
currLeftOffset: newLeftOffset
|
||||
currLeftOffset: newLeftOffset,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,15 +106,29 @@ export const withScrubbing = <P extends withScrubbingPropsI>(Component: React.Co
|
||||
|
||||
useEffect(()=>{
|
||||
console.log(`withSCRUBBING useEFFECT!! `);
|
||||
const positionInPercentage = prevLeftOffset/boundingWidth;
|
||||
if(onScrubChanged
|
||||
&& typeof positionInPercentage === "number"
|
||||
&& positionInPercentage >= 0
|
||||
){
|
||||
onScrubChanged(prevLeftOffset/boundingWidth);
|
||||
if(onScrubChanged && boundingWidth > 0 && prevLeftOffset >= 0 ){
|
||||
onScrubChanged(prevLeftOffset);
|
||||
}
|
||||
},[prevLeftOffset, boundingWidth, onScrubChanged]);
|
||||
|
||||
useEffect(()=>{
|
||||
// this takes a forced reset on leftoffset
|
||||
setStates((curr)=>{
|
||||
if(curr.prevLeftOffset === curr.currLeftOffset
|
||||
&& propsLeftOffset !== curr.prevLeftOffset
|
||||
&& propsLeftOffset !== curr.prevLeftOffset
|
||||
){
|
||||
return {
|
||||
...curr,
|
||||
currLeftOffset: propsLeftOffset, // in pixels
|
||||
prevLeftOffset: propsLeftOffset, //in pixels
|
||||
}
|
||||
}else{
|
||||
return curr
|
||||
}
|
||||
});
|
||||
}, [propsLeftOffset])
|
||||
|
||||
return(
|
||||
<div
|
||||
className="scrubber-wrapper"
|
||||
|
||||
@@ -104,7 +104,8 @@ $playbar-height: 2rem;
|
||||
.playcursor {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 0.5rem;
|
||||
width: 0.5rem; //=8px
|
||||
transform: translate(-3px, 0px);
|
||||
height: $playbar-height;
|
||||
background-color: $white;
|
||||
border-radius: 1px;
|
||||
|
||||
Reference in new issue
Block a user