aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2021-05-17 11:15:52 +0200
committerlonkaars <loek@pipeframe.xyz>2021-05-17 11:15:52 +0200
commit5a66728480dcf9ea3281d1bd887f610f8e6b7db4 (patch)
tree8bb221323f44f21f37e4d9adf2229bad5c8fe3dd
parent5890893a4c60af290843601252caf890360d29cf (diff)
timeline moves in editor to now
-rw-r--r--pages/editor.tsx44
-rw-r--r--pages/present.tsx13
-rw-r--r--styles/editor.css1
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)
}