diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-04-15 05:43:29 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-04-15 05:43:29 +0200 |
| commit | ac43a5a73fa905cdac905bc956763b6093d6738e (patch) | |
| tree | 8d9ff8c3a9ae55bac8860215bec69cc5b6094a1c /apps/web/src/components/editor/panels/timeline/index.tsx | |
| parent | 6312fc5b078689bc82c52fda9b7f92ee0a21d311 (diff) | |
| download | opencut-ac43a5a73fa905cdac905bc956763b6093d6738e.tar.gz | |
feat: move/resize multiple elements
Diffstat (limited to 'apps/web/src/components/editor/panels/timeline/index.tsx')
| -rw-r--r-- | apps/web/src/components/editor/panels/timeline/index.tsx | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/apps/web/src/components/editor/panels/timeline/index.tsx b/apps/web/src/components/editor/panels/timeline/index.tsx index ae9e19c9..20e9faf1 100644 --- a/apps/web/src/components/editor/panels/timeline/index.tsx +++ b/apps/web/src/components/editor/panels/timeline/index.tsx @@ -61,7 +61,6 @@ import { SELECTED_TRACK_ROW_CLASS } from "./theme"; import { computeTrackExpansionHeight, getTrackExpandedRows, - getExpansionHeight, getPropertyLabel, type ExpandedRow, } from "./expanded-layout"; @@ -75,6 +74,7 @@ import { TimelineBookmarksRow } from "./bookmarks"; import { useBookmarkDrag } from "@/hooks/timeline/use-bookmark-drag"; import { useEdgeAutoScroll } from "@/hooks/timeline/use-edge-auto-scroll"; import { useInitialScrollBottom } from "@/hooks/timeline/use-initial-scroll-bottom"; +import { useTimelineResize } from "@/hooks/timeline/use-timeline-resize"; import { useTimelineStore } from "@/stores/timeline-store"; import { useEditor } from "@/hooks/use-editor"; import { useTimelinePlayhead } from "@/hooks/timeline/use-timeline-playhead"; @@ -119,7 +119,9 @@ export function Timeline() { } = useElementSelection(); const editor = useEditor(); const timeline = editor.timeline; - const scene = useEditor((currentEditor) => currentEditor.scenes.getActiveSceneOrNull()); + const scene = useEditor((currentEditor) => + currentEditor.scenes.getActiveSceneOrNull(), + ); const tracks = useMemo<TimelineTrack[]>( () => scene @@ -140,7 +142,6 @@ export function Timeline() { const playheadRef = useRef<HTMLDivElement>(null); const trackLabelsScrollRef = useRef<HTMLDivElement>(null); - const [isResizing, setIsResizing] = useState(false); const [currentSnapPoint, setCurrentSnapPoint] = useState<SnapPoint | null>( null, ); @@ -148,15 +149,6 @@ export function Timeline() { const handleSnapPointChange = useCallback((snapPoint: SnapPoint | null) => { setCurrentSnapPoint(snapPoint); }, []); - const handleResizeStateChange = useCallback( - ({ isResizing: nextIsResizing }: { isResizing: boolean }) => { - setIsResizing(nextIsResizing); - if (!nextIsResizing) { - setCurrentSnapPoint(null); - } - }, - [], - ); const timelineDuration = timeline.getTotalDuration() || 0; const minZoomLevel = getTimelineZoomMin({ @@ -176,6 +168,10 @@ export function Timeline() { tracksScrollRef, rulerScrollRef, }); + const { isResizing, handleResizeStart } = useTimelineResize({ + zoomLevel, + onSnapPointChange: handleSnapPointChange, + }); const expandedElementIds = useTimelineStore((s) => s.expandedElementIds); @@ -366,7 +362,10 @@ export function Timeline() { const containerWidth = tracksContainerRef.current?.clientWidth || FALLBACK_CONTAINER_WIDTH; - const contentWidth = timelineTimeToPixels({ time: timelineDuration, zoomLevel }); + const contentWidth = timelineTimeToPixels({ + time: timelineDuration, + zoomLevel, + }); const paddingPx = getTimelinePaddingPx({ containerWidth, zoomLevel, @@ -513,7 +512,10 @@ export function Timeline() { TRACKS_CONTAINER_HEIGHT.min, Math.min( TRACKS_CONTAINER_HEIGHT.max, - getTotalTracksHeight({ tracks, getExtraHeight: getTrackExpansionHeight }), + getTotalTracksHeight({ + tracks, + getExtraHeight: getTrackExpansionHeight, + }), ), ) + TIMELINE_CONTENT_TOP_PADDING_PX }px`, @@ -533,14 +535,13 @@ export function Timeline() { }} > {tracks.length > 0 && ( - <TimelineTrackRows - mainTrackId={mainTrackId} + <TimelineTrackRows + mainTrackId={mainTrackId} zoomLevel={zoomLevel} dragState={dragState} tracksScrollRef={tracksScrollRef} lastMouseXRef={lastMouseXRef} - onSnapPointChange={handleSnapPointChange} - onResizeStateChange={handleResizeStateChange} + onResizeStart={handleResizeStart} onElementMouseDown={handleElementMouseDown} onElementClick={handleElementClick} onTrackMouseDown={(event) => { @@ -718,8 +719,7 @@ function TimelineTrackRows({ dragState, tracksScrollRef, lastMouseXRef, - onSnapPointChange, - onResizeStateChange, + onResizeStart, onElementMouseDown, onElementClick, onTrackMouseDown, @@ -733,8 +733,9 @@ function TimelineTrackRows({ dragState: ElementDragState; tracksScrollRef: React.RefObject<HTMLDivElement | null>; lastMouseXRef: React.RefObject<number>; - onSnapPointChange: (snapPoint: SnapPoint | null) => void; - onResizeStateChange: (params: { isResizing: boolean }) => void; + onResizeStart: React.ComponentProps< + typeof TimelineTrackContent + >["onResizeStart"]; onElementMouseDown: React.ComponentProps< typeof TimelineTrackContent >["onElementMouseDown"]; @@ -798,8 +799,7 @@ function TimelineTrackRows({ <div className={cn( "absolute right-0 left-0 transition-colors", - tracksWithSelection.has(track.id) && - SELECTED_TRACK_ROW_CLASS, + tracksWithSelection.has(track.id) && SELECTED_TRACK_ROW_CLASS, )} style={{ top: `${TIMELINE_CONTENT_TOP_PADDING_PX + getCumulativeHeightBefore({ tracks, trackIndex: index, getExtraHeight: getTrackExpansionHeight })}px`, @@ -813,8 +813,7 @@ function TimelineTrackRows({ rulerScrollRef={tracksScrollRef} tracksScrollRef={tracksScrollRef} lastMouseXRef={lastMouseXRef} - onSnapPointChange={onSnapPointChange} - onResizeStateChange={onResizeStateChange} + onResizeStart={onResizeStart} onElementMouseDown={onElementMouseDown} onElementClick={onElementClick} onTrackMouseDown={onTrackMouseDown} @@ -929,12 +928,10 @@ function TrackToggleIcon({ function PropertyTree({ rows }: { rows: ExpandedRow[] }) { return ( <div className="flex flex-col overflow-hidden"> - {rows.map((row, index) => ( + {rows.map((row) => ( <div key={row.propertyPath} - className={cn( - "flex shrink-0 items-center px-3 bg-muted/50", - )} + className={cn("flex shrink-0 items-center px-3 bg-muted/50")} style={{ height: `${KEYFRAME_LANE_HEIGHT_PX}px` }} > <span className="text-muted-foreground truncate text-xs leading-none"> |
