diff --git a/src/components/player/atoms/ProgressBar.tsx b/src/components/player/atoms/ProgressBar.tsx index e5810d0a..6b421a3d 100644 --- a/src/components/player/atoms/ProgressBar.tsx +++ b/src/components/player/atoms/ProgressBar.tsx @@ -13,22 +13,57 @@ import { nearestImageAt } from "@/stores/player/slices/thumbnails"; import { usePlayerStore } from "@/stores/player/store"; import { durationExceedsHour, formatSeconds } from "@/utils/formatSeconds"; -function ThumbnailDisplay(props: { at: number }) { +function ThumbnailDisplay(props: { at: number; show: boolean }) { const thumbnailImages = usePlayerStore((s) => s.thumbnails.images); const currentThumbnail = useMemo(() => { return nearestImageAt(thumbnailImages, props.at)?.image; }, [thumbnailImages, props.at]); + const [offsets, setOffsets] = useState({ + offscreenLeft: 0, + offscreenRight: 0, + }); + const ref = useRef(null); - if (!currentThumbnail) return null; + useEffect(() => { + if (!ref.current) return; + const rect = ref.current.getBoundingClientRect(); + const padding = 32; + const left = Math.max(0, (rect.left - padding) * -1); + const right = Math.max(0, rect.right + padding - window.innerWidth); + + setOffsets({ + offscreenLeft: left, + offscreenRight: right, + }); + }, [props.at]); + + if (!props.show || !currentThumbnail) return null; return (
- -

- {formatSeconds(props.at, durationExceedsHour(props.at))} -

+
+
+
0 + ? offsets.offscreenLeft + : -offsets.offscreenRight + }px)`, + }} + > + +

+ {formatSeconds( + Math.max(props.at, 0), + durationExceedsHour(props.at) + )} +

+
+
+
); } @@ -86,16 +121,17 @@ export function ProgressBar() { return (
- {mousePos > -1 ? ( -
- -
- ) : null} +
+ -1} + /> +