2026-04-28 17:11:42 +08:00

45 lines
1.4 KiB
TypeScript

interface ProgressBarProps {
progress: number;
onSeek: (ratio: number) => void;
}
export function ProgressBar({ progress, onSeek }: ProgressBarProps) {
const seekFromClientX = (clientX: number, element: HTMLElement) => {
const rect = element.getBoundingClientRect();
onSeek((clientX - rect.left) / rect.width);
};
return (
<div
className="relative h-1.5 rounded-full bg-white/25 overflow-hidden cursor-pointer touch-none"
onClick={(e) => {
seekFromClientX(e.clientX, e.currentTarget as HTMLElement);
}}
onPointerDown={(e) => {
if (e.pointerType === "mouse" && e.button !== 0) return;
e.currentTarget.setPointerCapture(e.pointerId);
seekFromClientX(e.clientX, e.currentTarget);
}}
onPointerMove={(e) => {
if (!e.currentTarget.hasPointerCapture(e.pointerId)) return;
seekFromClientX(e.clientX, e.currentTarget);
}}
onPointerUp={(e) => {
if (e.currentTarget.hasPointerCapture(e.pointerId)) {
e.currentTarget.releasePointerCapture(e.pointerId);
}
}}
onPointerCancel={(e) => {
if (e.currentTarget.hasPointerCapture(e.pointerId)) {
e.currentTarget.releasePointerCapture(e.pointerId);
}
}}
>
<div
className="origin-left h-full bg-white"
style={{ transform: `scaleX(${progress || 0})` }}
/>
</div>
);
}