unified-video-framework
Version:
Cross-platform video player framework supporting iOS, Android, Web, Smart TVs (Samsung/LG), Roku, and more
86 lines • 3.63 kB
JavaScript
import React, { useRef, useCallback, useState } from 'react';
export const PortraitProgressBar = ({ currentTime, duration, buffered, isPlaying, onSeek, }) => {
const barRef = useRef(null);
const [isDragging, setIsDragging] = useState(false);
const progress = duration > 0 ? (currentTime / duration) * 100 : 0;
const bufferedPct = duration > 0 ? (buffered / duration) * 100 : 0;
const expanded = !isPlaying || isDragging;
const seekFromEvent = useCallback((clientX) => {
const bar = barRef.current;
if (!bar || duration <= 0)
return;
const rect = bar.getBoundingClientRect();
const pct = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
onSeek(pct * duration);
}, [duration, onSeek]);
const onPointerDown = useCallback((e) => {
setIsDragging(true);
seekFromEvent(e.clientX);
e.target.setPointerCapture(e.pointerId);
}, [seekFromEvent]);
const onPointerMove = useCallback((e) => {
if (!isDragging)
return;
seekFromEvent(e.clientX);
}, [isDragging, seekFromEvent]);
const onPointerUp = useCallback(() => {
setIsDragging(false);
}, []);
return (React.createElement("div", { ref: barRef, "data-interactive": true, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, style: {
position: 'absolute',
bottom: expanded ? 8 : 0,
left: expanded ? 12 : 0,
right: expanded ? 12 : 0,
height: expanded ? 6 : 3,
borderRadius: expanded ? 3 : 0,
cursor: 'pointer',
zIndex: 20,
transition: 'bottom 0.3s ease, left 0.3s ease, right 0.3s ease, height 0.3s ease, border-radius 0.3s ease',
touchAction: 'none',
overflow: 'visible',
} },
React.createElement("div", { style: {
position: 'absolute',
inset: 0,
borderRadius: 'inherit',
background: 'rgba(255,255,255,0.2)',
} }),
React.createElement("div", { style: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
width: `${bufferedPct}%`,
borderRadius: 'inherit',
background: 'rgba(255,255,255,0.35)',
} }),
React.createElement("div", { style: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
width: `${progress}%`,
borderRadius: 'inherit',
background: '#f00',
transition: isDragging ? 'none' : 'width 0.1s linear',
} }),
React.createElement("div", { style: {
position: 'absolute',
top: '50%',
left: `${progress}%`,
width: isDragging ? 16 : 12,
height: isDragging ? 16 : 12,
borderRadius: '50%',
background: '#f00',
transform: 'translate(-50%, -50%)',
boxShadow: '0 0 4px rgba(0,0,0,0.5)',
opacity: expanded ? 1 : 0,
scale: expanded ? '1' : '0',
transition: isDragging
? 'opacity 0.2s ease, scale 0.2s ease'
: 'left 0.1s linear, width 0.15s ease, height 0.15s ease, opacity 0.3s ease, scale 0.3s ease',
pointerEvents: 'none',
zIndex: 1,
} })));
};
//# sourceMappingURL=PortraitProgressBar.js.map