mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 18:26:17 +00:00
61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
import { useCallback, useState, type MouseEvent, type PointerEvent, type RefObject } from "react";
|
|
import { getTimelineContentXFromClient } from "./timelineLayout";
|
|
|
|
interface TimelineRazorInteractionOptions {
|
|
active: boolean;
|
|
scrollRef: RefObject<HTMLDivElement | null>;
|
|
contentOrigin: number;
|
|
pixelsPerSecond: number;
|
|
onSplitAll?: (time: number) => void;
|
|
}
|
|
|
|
export function useTimelineRazorInteraction({
|
|
active,
|
|
scrollRef,
|
|
contentOrigin,
|
|
pixelsPerSecond,
|
|
onSplitAll,
|
|
}: TimelineRazorInteractionOptions) {
|
|
const [razorGuideX, setRazorGuideX] = useState<number | null>(null);
|
|
|
|
const updateRazorGuide = useCallback(
|
|
(event: MouseEvent<HTMLDivElement>) => {
|
|
const scroll = scrollRef.current;
|
|
if (!active || !scroll) return;
|
|
const rect = scroll.getBoundingClientRect();
|
|
setRazorGuideX(event.clientX - rect.left + scroll.scrollLeft);
|
|
},
|
|
[active, scrollRef],
|
|
);
|
|
|
|
const clearRazorGuide = useCallback(() => setRazorGuideX(null), []);
|
|
|
|
const splitAllAtPointer = useCallback(
|
|
(event: PointerEvent<HTMLDivElement>) => {
|
|
const scroll = scrollRef.current;
|
|
if (!active || !event.shiftKey || event.button !== 0 || !scroll) return false;
|
|
const rect = scroll.getBoundingClientRect();
|
|
const x = getTimelineContentXFromClient({
|
|
clientX: event.clientX,
|
|
rectLeft: rect.left,
|
|
scrollLeft: scroll.scrollLeft,
|
|
contentOrigin,
|
|
});
|
|
onSplitAll?.(Math.max(0, x / pixelsPerSecond));
|
|
return true;
|
|
},
|
|
[active, contentOrigin, onSplitAll, pixelsPerSecond, scrollRef],
|
|
);
|
|
|
|
return { razorGuideX, updateRazorGuide, clearRazorGuide, splitAllAtPointer };
|
|
}
|
|
|
|
export function TimelineRazorGuide({ x }: { x: number }) {
|
|
return (
|
|
<div
|
|
className="absolute top-0 bottom-0 pointer-events-none z-10"
|
|
style={{ left: x, width: 1, background: "rgba(239,68,68,0.7)" }}
|
|
/>
|
|
);
|
|
}
|