File size: 1,885 Bytes
ae238b3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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,
  };
};