From d6724e2552d14140017b194e7020252bda73751a Mon Sep 17 00:00:00 2001 From: leimingsheng Date: Mon, 21 Jul 2025 19:15:52 +0800 Subject: feat: init timeline zoom --- apps/web/src/components/editor/timeline.tsx | 78 +++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 22 deletions(-) (limited to 'apps/web/src/components/editor/timeline.tsx') diff --git a/apps/web/src/components/editor/timeline.tsx b/apps/web/src/components/editor/timeline.tsx index 9e68fd4d..84c228f0 100644 --- a/apps/web/src/components/editor/timeline.tsx +++ b/apps/web/src/components/editor/timeline.tsx @@ -56,6 +56,8 @@ import { TIMELINE_CONSTANTS, snapTimeToFrame, } from "@/constants/timeline-constants"; +import { TimelineZoomControl } from "./timeline-zoom-control"; +import { useTimelineZoomActions } from "@/hooks/use-timeline-zoom-actions"; export function Timeline() { // Timeline shows all tracks (video, audio, effects) and their elements. @@ -69,6 +71,7 @@ export function Timeline() { removeElementFromTrack, removeElementFromTrackWithRipple, getTotalDuration, + calculateFitToWindowZoom, selectedElements, clearSelectedElements, setSelectedElements, @@ -103,10 +106,20 @@ export function Timeline() { downTime: 0, }); + // Fit to window function + const handleFitToWindow = useCallback(() => { + if (timelineRef.current) { + const containerWidth = timelineRef.current.clientWidth; + const optimalZoom = calculateFitToWindowZoom(containerWidth); + setZoomLevel(optimalZoom); + } + }, [calculateFitToWindowZoom]); + // Timeline zoom functionality const { zoomLevel, setZoomLevel, handleWheel } = useTimelineZoom({ containerRef: timelineRef, isInTimeline, + onFitToWindow: handleFitToWindow, }); // Old marquee selection removed - using new SelectionBox component instead @@ -141,6 +154,13 @@ export function Timeline() { playheadRef, }); + // Zoom actions + useTimelineZoomActions({ + zoomLevel, + setZoomLevel, + onFitToWindow: handleFitToWindow, + }); + // Selection box functionality const tracksContainerRef = useRef(null); const { @@ -836,6 +856,15 @@ export function Timeline() { + + {/* Timeline Zoom Control */} +
+
@@ -880,21 +909,21 @@ export function Timeline() { {/* Timeline Ruler */}
- -
+
{/* Time markers */} {(() => { // Calculate appropriate time interval based on zoom level @@ -962,8 +991,7 @@ export function Timeline() { ); }).filter(Boolean); })()} -
- +
@@ -976,7 +1004,10 @@ export function Timeline() { className="w-48 flex-shrink-0 border-r border-black overflow-y-auto" data-track-labels > - +
{tracks.map((track) => (
{ handleTimelineMouseDown(e); @@ -1010,13 +1041,16 @@ export function Timeline() { onClick={handleTimelineContentClick} ref={tracksContainerRef} > - - +
+
)}
- +
-- cgit v1.3.1