diff options
author | lonkaars <loek@pipeframe.xyz> | 2021-05-17 11:15:52 +0200 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2021-05-17 11:15:52 +0200 |
commit | 5a66728480dcf9ea3281d1bd887f610f8e6b7db4 (patch) | |
tree | 8bb221323f44f21f37e4d9adf2229bad5c8fe3dd | |
parent | 5890893a4c60af290843601252caf890360d29cf (diff) |
timeline moves in editor to now
-rw-r--r-- | pages/editor.tsx | 44 | ||||
-rw-r--r-- | pages/present.tsx | 13 | ||||
-rw-r--r-- | styles/editor.css | 1 |
3 files changed, 41 insertions, 17 deletions
diff --git a/pages/editor.tsx b/pages/editor.tsx index 4f49dbb..8bf757f 100644 --- a/pages/editor.tsx +++ b/pages/editor.tsx @@ -34,6 +34,11 @@ var useTimelineLabels = create(set => ({ setLabels: (newLabels: Array<ReactNode>) => set(() => ({ labels: newLabels })), })); +var useFrame = create(set => ({ + currentFrame: 0, + setFrame: (newFrame: number) => set(() => ({ currentFrame: newFrame })), +})); + function TimelineEditor(props: { player: TimedVideoPlayer; }) { @@ -50,18 +55,26 @@ function TimelineEditor(props: { var timelineLabels = useTimelineLabels((st: any) => st.labels); var setTimelineLabels = useTimelineLabels((st: any) => st.setLabels); + var frame = useFrame((st: any) => st.currentFrame); + var setFrame = useFrame((st: any) => st.setFrame); + useEffect(() => { var canvas = document.getElementById('timeScaleCanvas') as HTMLCanvasElement; var ctx = canvas.getContext('2d'); - var mouseX = 0; - var mouseY = 0; + /* var mouseX = 0; */ + /* var mouseY = 0; */ - window.addEventListener('mousemove', e => { - var rect = canvas.getBoundingClientRect(); - mouseX = e.clientX - rect.x; - mouseY = e.clientY - rect.y; - }); + /* window.addEventListener('mousemove', e => { */ + /* var rect = canvas.getBoundingClientRect(); */ + /* mouseX = e.clientX - rect.x; */ + /* mouseY = e.clientY - rect.y; */ + /* }); */ + + function onframe(frame: number) { + setFrame(frame); + } + props.player.onframe = onframe; var css = (varname: string) => getComputedStyle(document.body).getPropertyValue(varname).trim(); var baseColor = css('--c100'); @@ -89,7 +102,7 @@ function TimelineEditor(props: { var rect = [Math.round(x + (frameWidth - 2) / 2), 28, 2, canvas.height]; var drawFrame = false; var marker = false; - if (frameWidth >= 3) { + if (frameWidth >= 6) { ctx.fillStyle = d ? baseColor : frameColor; rect = [x, 28, frameWidth, canvas.height]; drawFrame = !d; @@ -145,7 +158,7 @@ function TimelineEditor(props: { <canvas className='timeScale posabs a0' id='timeScaleCanvas' /> <div className='labels'>{timelineLabels}</div> <div className='timelineInner posabs a0'> - <div className='scrubber posabs v0'> + <div className='scrubber posabs v0' style={{ '--frame': frame.toString() } as CSSProperties}> <svg width='20' height='28' @@ -178,6 +191,8 @@ export default function Index() { var timelineZoom = getTimelineZoom((st: any) => st.zoom); var setTimelineZoom = getTimelineZoom((st: any) => st.setZoom); + var frame = useFrame((st: any) => st.currentFrame); + useEffect(() => { var videoEL = document.getElementById('player') as HTMLVideoElement; player.registerPlayer(videoEL); @@ -255,8 +270,13 @@ export default function Index() { <div className='controls'> <div className='posabs abscenter'> <Fab size='small' children={<SkipPreviousRoundedIcon />} /> - <Fab className='playPause' size='medium' children={<PauseRoundedIcon />} /> - <Fab size='small' children={<NavigateBeforeRoundedIcon />} /> + <Fab + className='playPause' + size='medium' + children={<PauseRoundedIcon />} + onClick={() => player.next()} + /> + <Fab size='small' children={<NavigateBeforeRoundedIcon />} onClick={() => player.previous()} /> <Fab size='small' children={<NavigateNextRoundedIcon />} /> </div> <div className='posabs abscenterv r0'> @@ -267,7 +287,7 @@ export default function Index() { <div className='tools'> <div className='time posrel'> <span className='framerate numbers posabs l0 t0'>@{player.framerate}fps</span> - <h2 className='timecode numbers posabs r0 t0'>00:00:00:00f</h2> + <h2 className='timecode numbers posabs r0 t0'>{player.frameToTimestampString(frame, false)}</h2> </div> <ButtonGroup color='primary' aria-label='outlined primary button group'> <Button children={<Icon path={mdiCursorDefault} size={1} />} /> diff --git a/pages/present.tsx b/pages/present.tsx index d1d18a2..085a99c 100644 --- a/pages/present.tsx +++ b/pages/present.tsx @@ -22,6 +22,7 @@ export class TimedVideoPlayer { registeredEventListeners: boolean; frame: number; framerate: number; + onframe?: (frame: number) => void; constructor() { this.slide = -1; @@ -31,13 +32,13 @@ export class TimedVideoPlayer { this.registeredEventListeners = false; } - frameToTimestampString(frame: number) { + frameToTimestampString(frame: number, trim: boolean = true) { var timecodeString = new Timecode(frame, this.framerate).toString(); - return timecodeString - .replace(/^(00:)+/, '') - .replace(';', '.') + if (trim) timecodeString = timecodeString.replace(/^(00:)+/, ''); + timecodeString = timecodeString.replace(';', '.') .replace(/(:)(\d+?)$/, '.$2') + 'f'; + return timecodeString; } timestampToFrame(timestamp: number): number { @@ -114,8 +115,12 @@ export class TimedVideoPlayer { setInterval(() => { if (this.player.paused) return; + + var lastFrame = this.frame; this.frame = this.timestampToFrame(this.player.currentTime); + if (this.frame != lastFrame && this.onframe) this.onframe(this.frame); + var slide = this.timeline.slides[this.slide]; if (!slide) return; diff --git a/styles/editor.css b/styles/editor.css index d1a6256..8d02dff 100644 --- a/styles/editor.css +++ b/styles/editor.css @@ -211,7 +211,6 @@ overflow: visible; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3)); z-index: 999999999; - --frame: 30; left: calc((var(--zoom) * (var(--frame) - 0.5)) * 1px - 1px) } |