summaryrefslogtreecommitdiff
path: root/apps/web/src/constants/timeline-constants.ts
blob: f670a3191949f87cc87de6477ed9ec2dac1edc63 (plain) (blame)
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import type { TrackType } from "@/types/timeline";

// Track color definitions
export const TRACK_COLORS: Record<
	TrackType,
	{ solid: string; background: string; border: string }
> = {
	media: {
		solid: "bg-blue-500",
		background: "bg-blue-500/20",
		border: "border-white/80",
	},
	text: {
		solid: "bg-[#9C4937]",
		background: "bg-[#9C4937]",
		border: "border-white/80",
	},
	audio: {
		solid: "bg-green-500",
		background: "bg-green-500/20",
		border: "border-white/80",
	},
} as const;

// Utility functions
export function getTrackColors(type: TrackType) {
	return TRACK_COLORS[type];
}

export function getTrackElementClasses(type: TrackType) {
	const colors = getTrackColors(type);
	return `${colors.background} ${colors.border}`;
}

// Track height definitions
export const TRACK_HEIGHTS: Record<TrackType, number> = {
	media: 65,
	text: 25,
	audio: 50,
} as const;

// Utility function for track heights
export function getTrackHeight(type: TrackType): number {
	return TRACK_HEIGHTS[type];
}

// Calculate cumulative height up to (but not including) a track index
export function getCumulativeHeightBefore(
	tracks: Array<{ type: TrackType }>,
	trackIndex: number,
): number {
	const GAP = 4; // 4px gap between tracks (equivalent to Tailwind's gap-1)
	return tracks
		.slice(0, trackIndex)
		.reduce((sum, track) => sum + getTrackHeight(track.type) + GAP, 0);
}

// Calculate total height of all tracks
export function getTotalTracksHeight(
	tracks: Array<{ type: TrackType }>,
): number {
	const GAP = 4; // 4px gap between tracks (equivalent to Tailwind's gap-1)
	const tracksHeight = tracks.reduce(
		(sum, track) => sum + getTrackHeight(track.type),
		0,
	);
	const gapsHeight = Math.max(0, tracks.length - 1) * GAP; // n-1 gaps for n tracks
	return tracksHeight + gapsHeight;
}

// Other timeline constants
export const TIMELINE_CONSTANTS = {
	ELEMENT_MIN_WIDTH: 80,
	PIXELS_PER_SECOND: 50,
	TRACK_HEIGHT: 60, // Default fallback
	DEFAULT_TEXT_DURATION: 5,
	DEFAULT_IMAGE_DURATION: 5,
	ZOOM_LEVELS: [0.25, 0.5, 1, 1.5, 2, 3, 4],
} as const;

// FPS presets for project settings
export const FPS_PRESETS = [
	{ value: "24", label: "24 fps (Film)" },
	{ value: "25", label: "25 fps (PAL)" },
	{ value: "30", label: "30 fps (NTSC)" },
	{ value: "60", label: "60 fps (High)" },
	{ value: "120", label: "120 fps (Slow-mo)" },
] as const;

// Frame snapping utilities
export function timeToFrame(time: number, fps: number): number {
	return Math.round(time * fps);
}

export function frameToTime(frame: number, fps: number): number {
	return frame / fps;
}

export function snapTimeToFrame(time: number, fps: number): number {
	if (fps <= 0) return time; // Fallback for invalid FPS
	const frame = timeToFrame(time, fps);
	return frameToTime(frame, fps);
}

export function getFrameDuration(fps: number): number {
	return 1 / fps;
}