aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2021-05-18 09:57:18 +0200
committerlonkaars <loek@pipeframe.xyz>2021-05-18 09:57:18 +0200
commite5319e20e5c329699d5ddf4cfa782ce3eed06fe5 (patch)
tree9a16eea3fd177b55bf923f4fc7f1a0322e1c6223
parent5a66728480dcf9ea3281d1bd887f610f8e6b7db4 (diff)
timeline zoom pivot
-rw-r--r--pages/editor.tsx52
1 files changed, 32 insertions, 20 deletions
diff --git a/pages/editor.tsx b/pages/editor.tsx
index 8bf757f..81a0c66 100644
--- a/pages/editor.tsx
+++ b/pages/editor.tsx
@@ -24,11 +24,12 @@ import SkipPreviousRoundedIcon from '@material-ui/icons/SkipPreviousRounded';
import { mdiCursorDefault } from '@mdi/js';
var getTimelineZoom = create(set => ({
- zoom: 0.2,
- changeZoom: (delta: number) => set((st: any) => ({ zoom: Math.min(1, Math.max(0, st.zoom + delta)) })),
+ zoom: 0.687077725615,
setZoom: (newValue: number) => set(() => ({ zoom: newValue })),
}));
+var zoomToPx = (zoom: number) => (12 - 0.5) * zoom ** (1 / 0.4) + 0.5;
+
var useTimelineLabels = create(set => ({
labels: [],
setLabels: (newLabels: Array<ReactNode>) => set(() => ({ labels: newLabels })),
@@ -62,15 +63,6 @@ function TimelineEditor(props: {
var canvas = document.getElementById('timeScaleCanvas') as HTMLCanvasElement;
var ctx = canvas.getContext('2d');
- /* var mouseX = 0; */
- /* var mouseY = 0; */
-
- /* window.addEventListener('mousemove', e => { */
- /* var rect = canvas.getBoundingClientRect(); */
- /* mouseX = e.clientX - rect.x; */
- /* mouseY = e.clientY - rect.y; */
- /* }); */
-
function onframe(frame: number) {
setFrame(frame);
}
@@ -107,10 +99,6 @@ function TimelineEditor(props: {
rect = [x, 28, frameWidth, canvas.height];
drawFrame = !d;
}
- /* if (a * 2 % everyN == 0) { */
- /* ctx.fillStyle = frameColor; */
- /* drawFrame = true; */
- /* } */
if (a % everyN == 0) {
ctx.fillStyle = markerFrame;
drawFrame = true;
@@ -146,7 +134,7 @@ function TimelineEditor(props: {
draw();
function onresize() {
- var size = document.querySelector('.timeline .timelineInner .keyframes');
+ var size = document.querySelector('.timeline .timelineInner');
canvas.width = size.clientWidth;
canvas.height = size.clientHeight;
}
@@ -193,21 +181,44 @@ export default function Index() {
var frame = useFrame((st: any) => st.currentFrame);
+ var mouseX = 0;
+ var mouseY = 0;
+
useEffect(() => {
var videoEL = document.getElementById('player') as HTMLVideoElement;
player.registerPlayer(videoEL);
}, []);
- var changeZoom = getTimelineZoom(st => (st as any).changeZoom);
+ function zoomAroundPoint(newZoom: number, pivot: number) {
+ var timeline = document.querySelector('.timeline .timelineInner');
+ var currentOffset = timeline.scrollLeft;
+ var frame = (pivot + currentOffset) / zoomToPx(timelineZoom);
+ var newOffset = (frame * zoomToPx(newZoom)) - pivot;
+
+ timeline.scrollLeft = newOffset;
+ setTimelineZoom(newZoom);
+ timelineZoom = newZoom;
+ }
+
useEffect(() => {
document.querySelector('.timeline').addEventListener('wheel', (e: WheelEvent) => {
if (!e.ctrlKey && !e.altKey) return;
e.preventDefault();
- changeZoom(-e.deltaY / 1000);
+ var newZoom = Math.min(1, Math.max(0, timelineZoom + (-e.deltaY / 1000)));
+ zoomAroundPoint(newZoom, mouseX);
}, { passive: false });
}, []);
+ useEffect(() => {
+ var canvas = document.querySelector('.timeline .timeScale');
+ window.addEventListener('mousemove', e => {
+ var rect = canvas.getBoundingClientRect();
+ mouseX = e.clientX - rect.x;
+ mouseY = e.clientY - rect.y;
+ });
+ }, []);
+
return <>
<div className='appGrid posabs a0'>
<AppBar position='static' color='transparent' elevation={0}>
@@ -311,7 +322,8 @@ export default function Index() {
<Slider
value={timelineZoom}
onChange={(event: any, newValue: number | number[]) => {
- setTimelineZoom(newValue as number);
+ var center = document.querySelector('.timeline .timelineInner').clientWidth / 2;
+ zoomAroundPoint(newValue as number, center);
}}
min={0}
step={0.00000001}
@@ -324,7 +336,7 @@ export default function Index() {
</div>
<div
className='timeline posrel'
- style={{ '--zoom': (12 - 0.5) * timelineZoom ** (1 / 0.4) + 0.5 } as CSSProperties}
+ style={{ '--zoom': zoomToPx(timelineZoom) } as CSSProperties}
>
<TimelineEditor
player={player}