手动分割调整
This commit is contained in:
+106
-102
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user