feat: init timeline zoom

This commit is contained in:
leimingsheng 2025-07-21 19:22:27 +08:00
parent d6724e2552
commit 768a1dbfbc
3 changed files with 11 additions and 7 deletions

View File

@ -75,7 +75,9 @@ export const TIMELINE_CONSTANTS = {
TRACK_HEIGHT: 60, // Default fallback TRACK_HEIGHT: 60, // Default fallback
DEFAULT_TEXT_DURATION: 5, DEFAULT_TEXT_DURATION: 5,
DEFAULT_IMAGE_DURATION: 5, DEFAULT_IMAGE_DURATION: 5,
ZOOM_LEVELS: [0.25, 0.5, 1, 1.5, 2, 3, 4], ZOOM_LEVELS: [0.5, 1, 1.5, 2, 3, 4, 5],
MIN_ZOOM: 0.5,
MAX_ZOOM: 5,
} as const; } as const;
// FPS presets for project settings // FPS presets for project settings

View File

@ -13,6 +13,8 @@ interface UseTimelineZoomReturn {
} }
const ZOOM_STORAGE_KEY = 'opencut-timeline-zoom'; const ZOOM_STORAGE_KEY = 'opencut-timeline-zoom';
const MIN_ZOOM = 0.5; // Minimum zoom to keep element borders visible
const MAX_ZOOM = 5;
export function useTimelineZoom({ export function useTimelineZoom({
containerRef, containerRef,
@ -25,7 +27,7 @@ export function useTimelineZoom({
const stored = localStorage.getItem(ZOOM_STORAGE_KEY); const stored = localStorage.getItem(ZOOM_STORAGE_KEY);
if (stored) { if (stored) {
const parsed = parseFloat(stored); const parsed = parseFloat(stored);
if (!isNaN(parsed) && parsed >= 0.1 && parsed <= 5) { if (!isNaN(parsed) && parsed >= MIN_ZOOM && parsed <= MAX_ZOOM) {
return parsed; return parsed;
} }
} }
@ -45,7 +47,7 @@ export function useTimelineZoom({
if (e.ctrlKey || e.metaKey) { if (e.ctrlKey || e.metaKey) {
e.preventDefault(); e.preventDefault();
const delta = e.deltaY > 0 ? -0.15 : 0.15; const delta = e.deltaY > 0 ? -0.15 : 0.15;
setZoomLevel((prev) => Math.max(0.1, Math.min(5, prev + delta))); setZoomLevel((prev) => Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, prev + delta)));
} }
// Otherwise, allow normal scrolling // Otherwise, allow normal scrolling
}, []); }, []);
@ -61,11 +63,11 @@ export function useTimelineZoom({
case '=': case '=':
case '+': case '+':
e.preventDefault(); e.preventDefault();
setZoomLevel((prev) => Math.min(5, prev + 0.2)); setZoomLevel((prev) => Math.min(MAX_ZOOM, prev + 0.2));
break; break;
case '-': case '-':
e.preventDefault(); e.preventDefault();
setZoomLevel((prev) => Math.max(0.1, prev - 0.2)); setZoomLevel((prev) => Math.max(MIN_ZOOM, prev - 0.2));
break; break;
case '0': case '0':
e.preventDefault(); e.preventDefault();

View File

@ -1173,8 +1173,8 @@ export const useTimelineStore = create<TimelineStore>((set, get) => {
const requiredWidth = totalDuration * TIMELINE_CONSTANTS.PIXELS_PER_SECOND; const requiredWidth = totalDuration * TIMELINE_CONSTANTS.PIXELS_PER_SECOND;
const calculatedZoom = availableWidth / requiredWidth; const calculatedZoom = availableWidth / requiredWidth;
// Clamp between min and max zoom levels // Clamp between min and max zoom levels (0.3 to 5)
return Math.max(0.1, Math.min(5, calculatedZoom)); return Math.max(0.5, Math.min(5, calculatedZoom));
}, },
redo: () => { redo: () => {