thumbnail styling

Co-authored-by: Jip Frijlink <JipFr@users.noreply.github.com>
This commit is contained in:
mrjvs 2023-10-21 16:39:20 +02:00
parent 068b7071a4
commit fcec845f21

View File

@ -13,23 +13,58 @@ import { nearestImageAt } from "@/stores/player/slices/thumbnails";
import { usePlayerStore } from "@/stores/player/store"; import { usePlayerStore } from "@/stores/player/store";
import { durationExceedsHour, formatSeconds } from "@/utils/formatSeconds"; 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 thumbnailImages = usePlayerStore((s) => s.thumbnails.images);
const currentThumbnail = useMemo(() => { const currentThumbnail = useMemo(() => {
return nearestImageAt(thumbnailImages, props.at)?.image; return nearestImageAt(thumbnailImages, props.at)?.image;
}, [thumbnailImages, props.at]); }, [thumbnailImages, props.at]);
const [offsets, setOffsets] = useState({
offscreenLeft: 0,
offscreenRight: 0,
});
const ref = useRef<HTMLImageElement>(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 ( return (
<div className="flex flex-col items-center -translate-x-1/2"> <div className="flex flex-col items-center -translate-x-1/2">
<div className="w-screen flex justify-center">
<div ref={ref}>
<div
style={{
transform: `translateX(${
offsets.offscreenLeft > 0
? offsets.offscreenLeft
: -offsets.offscreenRight
}px)`,
}}
>
<img <img
src={currentThumbnail.data} src={currentThumbnail.data}
className="h-24 border rounded-xl border-gray-800" className="h-24 border rounded-xl border-gray-800"
/> />
<p className="text-center"> <p className="text-center mt-1">
{formatSeconds(props.at, durationExceedsHour(props.at))} {formatSeconds(
Math.max(props.at, 0),
durationExceedsHour(props.at)
)}
</p> </p>
</div> </div>
</div>
</div>
</div>
); );
} }
@ -86,16 +121,17 @@ export function ProgressBar() {
return ( return (
<div className="w-full relative"> <div className="w-full relative">
<div className="top-0 absolute inset-x-0"> <div className="top-0 absolute inset-x-0">
{mousePos > -1 ? (
<div <div
className="absolute bottom-0" className="absolute bottom-0"
style={{ style={{
left: `${mousePos}%`, left: `${mousePos}%`,
}} }}
> >
<ThumbnailDisplay at={Math.floor((mousePos / 100) * duration)} /> <ThumbnailDisplay
at={Math.floor((mousePos / 100) * duration)}
show={mousePos > -1}
/>
</div> </div>
) : null}
</div> </div>
<div className="w-full" ref={ref}> <div className="w-full" ref={ref}>