手动分割调整

This commit is contained in:
孙佳艺
2026-06-25 16:04:57 +08:00
parent a0a60bd121
commit 78c3f36ca2
3 changed files with 243 additions and 208 deletions
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -28,7 +28,7 @@
} }
})(); })();
</script> </script>
<script type="module" crossorigin src="/assets/index-BjRp0K8U.js"></script> <script type="module" crossorigin src="/assets/index-DUhIsGse.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-eLRg4pQk.css"> <link rel="stylesheet" crossorigin href="/assets/index-eLRg4pQk.css">
</head> </head>
<body> <body>
@@ -243,6 +243,7 @@ const VideoTrimPicker: React.FC<VideoTrimPickerProps> = ({
const abortRef = useRef(false); const abortRef = useRef(false);
const rangeRef = useRef<[number, number]>([0, minDuration]); const rangeRef = useRef<[number, number]>([0, minDuration]);
const currentTimeRef = useRef(0); const currentTimeRef = useRef(0);
const frameContainerRef = useRef<HTMLDivElement>(null);
const [duration, setDuration] = useState(0); const [duration, setDuration] = useState(0);
const [currentTime, setCurrentTime] = useState(0); const [currentTime, setCurrentTime] = useState(0);
@@ -380,8 +381,13 @@ const VideoTrimPicker: React.FC<VideoTrimPickerProps> = ({
const handleRangeChange = useCallback((value: number[]) => { const handleRangeChange = useCallback((value: number[]) => {
if (!integerDuration) return; if (!integerDuration) return;
setLocalError(''); setLocalError('');
setRange((prev) => normalizeRange([Number(value[0]), Number(value[1])], prev, integerDuration, minDuration, maxDuration)); const nextRange = [Number(value[0]), Number(value[1])] as [number, number];
}, [integerDuration, maxDuration, minDuration, setRange]); const clamped = [
Math.max(0, Math.min(integerDuration, nextRange[0])),
Math.max(nextRange[0], Math.min(integerDuration, nextRange[1])),
] as [number, number];
setRange(clamped);
}, [integerDuration, setRange]);
const handleRangeChangeComplete = useCallback(() => { const handleRangeChangeComplete = useCallback(() => {
seekPreview(rangeRef.current[0]); seekPreview(rangeRef.current[0]);
@@ -534,21 +540,41 @@ const VideoTrimPicker: React.FC<VideoTrimPickerProps> = ({
</span> </span>
</div> </div>
<div style={{ position: 'relative', padding: '0 6px' }}> <div
ref={frameContainerRef}
style={{
overflowX: 'auto',
overflowY: 'hidden',
scrollbarWidth: 'none',
msOverflowStyle: 'none',
padding: '0 6px',
}}
>
<style>{`
div::-webkit-scrollbar {
display: none;
}
`}</style>
<div <div
style={{ style={{
display: 'grid', margin: 'auto',
gridTemplateColumns: `repeat(${Math.max(frames.length, 1)}, minmax(0, 1fr))`, display: 'flex',
flexDirection: 'column',
width: frames.length > 0 ? `${frames.length * 80 + Math.max(0, frames.length - 1) * 1}px` : '100%',
}}
>
<div
style={{
display: 'flex',
height: 86, height: 86,
overflow: 'hidden',
borderRadius: 12, borderRadius: 12,
background: '#fff', background: '#fff',
position: 'relative',
gap: 1, gap: 1,
position: 'relative',
}} }}
> >
{frameLoading && frames.length === 0 ? ( {frameLoading && frames.length === 0 ? (
<div style={{ gridColumn: '1 / -1', display: 'flex', alignItems: 'center', justifyContent: 'center' }}> <div style={{ flex: '1 1 auto', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<Spin size="small" /> <Spin size="small" />
<Text style={{ marginLeft: 8, color: '#64748b' }}>...</Text> <Text style={{ marginLeft: 8, color: '#64748b' }}>...</Text>
</div> </div>
@@ -562,7 +588,8 @@ const VideoTrimPicker: React.FC<VideoTrimPickerProps> = ({
onClick={() => handleFrameClick(frame.second)} onClick={() => handleFrameClick(frame.second)}
title={`${frame.second}s${frame.fallback ? `,实际取帧 ${frame.captureSecond?.toFixed(1)}s` : ''}`} title={`${frame.second}s${frame.fallback ? `,实际取帧 ${frame.captureSecond?.toFixed(1)}s` : ''}`}
style={{ style={{
minWidth: 0, minWidth: 80,
flex: '0 0 80px',
height: 86, height: 86,
borderTop: isSelected ? '5px solid #6366f1' : 'none', borderTop: isSelected ? '5px solid #6366f1' : 'none',
borderBottom: isSelected ? '5px solid #6366f1' : 'none', borderBottom: isSelected ? '5px solid #6366f1' : 'none',
@@ -571,7 +598,6 @@ const VideoTrimPicker: React.FC<VideoTrimPickerProps> = ({
overflow: 'hidden', overflow: 'hidden',
cursor: disabledByDuration ? 'not-allowed' : 'pointer', cursor: disabledByDuration ? 'not-allowed' : 'pointer',
position: 'relative', position: 'relative',
// borderRadius: 4,
}} }}
> >
{frame.status === 'success' && frame.image ? ( {frame.status === 'success' && frame.image ? (
@@ -592,7 +618,7 @@ const VideoTrimPicker: React.FC<VideoTrimPickerProps> = ({
left: 0, left: 0,
bottom: 3, bottom: 3,
color: '#ffffffff', color: '#ffffffff',
fontSize: 10, fontSize: 16,
textShadow: '0 1px 3px rgba(0,0,0,.7)', textShadow: '0 1px 3px rgba(0,0,0,.7)',
}} }}
> >
@@ -602,14 +628,20 @@ const VideoTrimPicker: React.FC<VideoTrimPickerProps> = ({
); );
}) })
) : ( ) : (
<div style={{ gridColumn: '1 / -1', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#64748b' }}> <div style={{ flex: '1 1 auto', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#64748b' }}>
</div> </div>
)} )}
</div> <div
style={{
<div style={{ position: 'absolute', top: -6, left: 6, right: 0, }}> position: 'absolute',
top: -10,
left: 0,
right: 0,
bottom: 0,
}}
>
<Slider <Slider
range range
min={0} min={0}
@@ -623,27 +655,26 @@ const VideoTrimPicker: React.FC<VideoTrimPickerProps> = ({
styles={{ styles={{
track: { track: {
background: '#6969dd63', background: '#6969dd63',
height: 70, height: 86,
borderRadius: 3, borderRadius: 12,
margin: '0 ', margin: '0 ',
}, },
rail: { rail: {
// background: '#0e447e70', height: 86,
height: 70, borderRadius: 12,
borderRadius: 3,
}, },
handle: { handle: {
width: 20, width: 20,
height: 70, height: 86,
marginTop: 0, marginTop: 0,
// backgroundColor: '#fff',
// border: '2px solid #6366f1',
borderRadius: '50%', borderRadius: '50%',
}, },
}} }}
/> />
</div> </div>
</div> </div>
</div>
</div>
<div style={{ marginTop: 16, textAlign: 'center', color: '#64748b', fontSize: 14 }}> <div style={{ marginTop: 16, textAlign: 'center', color: '#64748b', fontSize: 14 }}>
{selectedDuration}s {selectedDuration}s