This commit is contained in:
Maze Winther
2026-01-16 18:07:28 +01:00
parent 0dddf4e13d
commit 0934db2aba
60 changed files with 1900 additions and 1202 deletions
@@ -245,6 +245,7 @@ export function useElementInteraction({
element: TimelineElement;
track: TimelineTrack;
}) => {
event.stopPropagation();
mouseDownLocationRef.current = { x: event.clientX, y: event.clientY };
const isRightClick = event.button === 2;
@@ -11,7 +11,6 @@ interface UseTimelineInteractionsProps {
zoomLevel: number;
duration: number;
isSelecting: boolean;
justFinishedSelecting: boolean;
clearSelectedElements: () => void;
seek: (time: number) => void;
}
@@ -23,7 +22,6 @@ export function useTimelineInteractions({
zoomLevel,
duration,
isSelecting,
justFinishedSelecting,
clearSelectedElements,
seek,
}: UseTimelineInteractionsProps) {
@@ -71,7 +69,7 @@ export function useTimelineInteractions({
if (deltaX > 5 || deltaY > 5 || deltaTime > 500) return false;
if (isSelecting || justFinishedSelecting) return false;
if (isSelecting) return false;
if (target.closest(".timeline-element")) return false;
@@ -84,7 +82,7 @@ export function useTimelineInteractions({
return true;
},
[isSelecting, justFinishedSelecting, clearSelectedElements, playheadRef],
[isSelecting, clearSelectedElements, playheadRef],
);
const handleTimelineSeek = useCallback(
@@ -91,25 +91,6 @@ export function useTimelinePlayhead({
const fps = activeProject.settings.fps;
const time = snapTimeToFrame({ time: rawTime, fps });
// debug logging
if (rawX < 0 || x !== rawX) {
console.log(
"PLAYHEAD DEBUG:",
JSON.stringify({
mouseX: event.clientX,
rulerLeft: rect.left,
rawX,
constrainedX: x,
timelineContentWidth,
rawTime,
finalTime: time,
duration,
zoomLevel,
playheadPx: time * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel,
}),
);
}
setScrubTime(time);
seek(time); // update video preview in real time
@@ -35,14 +35,14 @@ export function useTimelineZoom({
// pinch-zoom (ctrl/meta + wheel)
if (isZoomGesture) {
event.preventDefault();
const zoomMultiplier = event.deltaY > 0 ? 1 / 1.1 : 1.1;
setZoomLevel((prev) =>
Math.max(
setZoomLevel((prev) => {
const nextZoom = Math.max(
TIMELINE_CONSTANTS.ZOOM_MIN,
Math.min(TIMELINE_CONSTANTS.ZOOM_MAX, prev * zoomMultiplier),
),
);
);
return nextZoom;
});
// for horizontal scrolling (when shift is held or horizontal wheel movement),
// let the event bubble up to allow ScrollArea to handle it
return;
@@ -51,25 +51,25 @@ export function useTimelineZoom({
// prevent browser zoom in the timeline
useEffect(() => {
const preventZoom = ({
ctrlKey,
metaKey,
target,
preventDefault,
}: WheelEvent) => {
if (
isInTimeline &&
(ctrlKey || metaKey) &&
containerRef.current?.contains(target as Node)
) {
preventDefault();
const preventZoom = (event: WheelEvent) => {
const isZoomKeyPressed = event.ctrlKey || event.metaKey;
const isInContainer = containerRef.current?.contains(
event.target as Node,
);
const shouldPrevent =
isInTimeline && isZoomKeyPressed && Boolean(isInContainer);
if (shouldPrevent) {
event.preventDefault();
}
};
document.addEventListener("wheel", preventZoom, { passive: false });
document.addEventListener("wheel", preventZoom, {
passive: false,
capture: true,
});
return () => {
document.removeEventListener("wheel", preventZoom);
document.removeEventListener("wheel", preventZoom, { capture: true });
};
}, [isInTimeline, containerRef]);