omniasr-transcriptions / frontend /src /hooks /useTimelineGeometry.ts
jeanma's picture
Omnilingual ASR transcription demo
ae238b3 verified
import { useCallback, useMemo } from 'react';
interface UseTimelineGeometryOptions {
mediaDuration: number;
constants: {
TRACK_HEIGHT: number;
TRACK_PADDING: number;
TIMELINE_PADDING: number;
PIXELS_PER_SECOND: number;
};
}
export const useTimelineGeometry = ({
mediaDuration,
constants,
}: UseTimelineGeometryOptions) => {
const { TRACK_HEIGHT, TRACK_PADDING, TIMELINE_PADDING, PIXELS_PER_SECOND } = constants;
// Calculate timeline dimensions
const timelineWidth = useMemo(() =>
mediaDuration * PIXELS_PER_SECOND,
[mediaDuration, PIXELS_PER_SECOND]
);
// Convert time to x position
const timeToX = useCallback((time: number) => {
return TIMELINE_PADDING + (time / mediaDuration) * (timelineWidth - TIMELINE_PADDING * 2);
}, [mediaDuration, timelineWidth, TIMELINE_PADDING]);
// Convert x position to time
const xToTime = useCallback((x: number) => {
return ((x - TIMELINE_PADDING) / (timelineWidth - TIMELINE_PADDING * 2)) * mediaDuration;
}, [mediaDuration, timelineWidth, TIMELINE_PADDING]);
// Convert track to y position
const trackToY = useCallback((track: number) => {
return TIMELINE_PADDING + track * (TRACK_HEIGHT + TRACK_PADDING);
}, [TRACK_HEIGHT, TRACK_PADDING, TIMELINE_PADDING]);
// Convert canvas coordinates to time (accounting for scroll)
const canvasXToTime = useCallback((canvasX: number) => {
return xToTime(canvasX);
}, [xToTime]);
// Convert client coordinates to canvas coordinates
const clientXToCanvasX = useCallback((clientX: number, canvasRef: React.RefObject<HTMLCanvasElement>) => {
const canvas = canvasRef.current;
if (!canvas) return 0;
const rect = canvas.getBoundingClientRect();
return clientX - rect.left;
}, []);
return {
timelineWidth,
timeToX,
xToTime,
trackToY,
canvasXToTime,
clientXToCanvasX,
};
};