From 63e21763ec5d2cd15589d3ca985311e65038ef9f Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:54:02 -0600 Subject: [PATCH] keep handlebar centered when zooming --- .../timeline/EventReviewTimeline.tsx | 21 ++++++++++++-- .../timeline/MotionReviewTimeline.tsx | 29 +++++++++++++++++-- .../timeline/VirtualizedEventSegments.tsx | 14 +++++++-- .../timeline/VirtualizedMotionSegments.tsx | 14 +++++++-- 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/web/src/components/timeline/EventReviewTimeline.tsx b/web/src/components/timeline/EventReviewTimeline.tsx index 1f460b32e..4160cd244 100644 --- a/web/src/components/timeline/EventReviewTimeline.tsx +++ b/web/src/components/timeline/EventReviewTimeline.tsx @@ -116,14 +116,31 @@ export function EventReviewTimeline({ ]); const scrollToSegment = useCallback( - (segmentTime: number, ifNeeded?: boolean) => { + (segmentTime: number, ifNeeded?: boolean, behavior?: ScrollBehavior) => { if (virtualizedSegmentsRef.current) { - virtualizedSegmentsRef.current.scrollToSegment(segmentTime, ifNeeded); + virtualizedSegmentsRef.current.scrollToSegment( + segmentTime, + ifNeeded, + behavior, + ); } }, [], ); + // keep handlebar centered when zooming + useEffect(() => { + setTimeout(() => { + scrollToSegment( + alignStartDateToTimeline(handlebarTime ?? timelineStart), + true, + "auto", + ); + }, 0); + // we only want to scroll when zooming level changes + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [segmentDuration]); + return ( { + (segmentTime: number, ifNeeded?: boolean, behavior?: ScrollBehavior) => { if (virtualizedSegmentsRef.current) { - virtualizedSegmentsRef.current.scrollToSegment(segmentTime, ifNeeded); + virtualizedSegmentsRef.current.scrollToSegment( + segmentTime, + ifNeeded, + behavior, + ); } }, [], ); + // keep handlebar centered when zooming + useEffect(() => { + setTimeout(() => { + scrollToSegment( + alignStartDateToTimeline(handlebarTime ?? timelineStart), + true, + "auto", + ); + }, 0); + // we only want to scroll when zooming level changes + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [segmentDuration]); + return ( void; + scrollToSegment: ( + segmentTime: number, + ifNeeded?: boolean, + behavior?: ScrollBehavior, + ) => void; } const SEGMENT_HEIGHT = 8; @@ -93,7 +97,11 @@ export const VirtualizedEventSegments = forwardRef< }, [updateVisibleRange, timelineRef]); const scrollToSegment = useCallback( - (segmentTime: number, ifNeeded: boolean = true) => { + ( + segmentTime: number, + ifNeeded: boolean = true, + behavior: ScrollBehavior = "smooth", + ) => { const alignedSegmentTime = alignStartDateToTimeline(segmentTime); const segmentIndex = segments.findIndex( (time) => time === alignedSegmentTime, @@ -115,7 +123,7 @@ export const VirtualizedEventSegments = forwardRef< if (!ifNeeded || !isVisible) { timelineRef.current.scrollTo({ top: Math.max(0, centeredScrollTop), - behavior: "smooth", + behavior: behavior, }); } updateVisibleRange(); diff --git a/web/src/components/timeline/VirtualizedMotionSegments.tsx b/web/src/components/timeline/VirtualizedMotionSegments.tsx index c0db7d043..3aed75266 100644 --- a/web/src/components/timeline/VirtualizedMotionSegments.tsx +++ b/web/src/components/timeline/VirtualizedMotionSegments.tsx @@ -27,7 +27,11 @@ type VirtualizedMotionSegmentsProps = { }; export interface VirtualizedMotionSegmentsRef { - scrollToSegment: (segmentTime: number, ifNeeded?: boolean) => void; + scrollToSegment: ( + segmentTime: number, + ifNeeded?: boolean, + behavior?: ScrollBehavior, + ) => void; } const SEGMENT_HEIGHT = 8; @@ -93,7 +97,11 @@ export const VirtualizedMotionSegments = forwardRef< }, [updateVisibleRange, timelineRef]); const scrollToSegment = useCallback( - (segmentTime: number, ifNeeded: boolean = true) => { + ( + segmentTime: number, + ifNeeded: boolean = true, + behavior: ScrollBehavior = "smooth", + ) => { const segmentIndex = segments.findIndex((time) => time === segmentTime); if ( segmentIndex !== -1 && @@ -112,7 +120,7 @@ export const VirtualizedMotionSegments = forwardRef< if (!ifNeeded || !isVisible) { timelineRef.current.scrollTo({ top: Math.max(0, centeredScrollTop), - behavior: "smooth", + behavior: behavior, }); } updateVisibleRange();