Improve waveform selection behaviour
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
c8de6643e8
commit
34681821e4
|
@ -210,26 +210,26 @@ function App(): JSX.Element {
|
|||
|
||||
setPositionFromFrame(newViewport.start);
|
||||
},
|
||||
[mediaSet, audio, video]
|
||||
[mediaSet, audio, video, selection]
|
||||
);
|
||||
|
||||
// handler called when the selection in the main waveform view is changed.
|
||||
const handleWaveformSelectionChange = useCallback(
|
||||
(selection: Frames) => {
|
||||
setSelection(selection);
|
||||
(newSelection: Frames) => {
|
||||
setSelection(newSelection);
|
||||
|
||||
if (mediaSet == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// move playback position to start of selection
|
||||
const ratio = selection.start / mediaSet.audioFrames;
|
||||
const ratio = newSelection.start / mediaSet.audioFrames;
|
||||
const currentTime =
|
||||
(mediaSet.audioFrames / mediaSet.audioSampleRate) * ratio;
|
||||
audio.currentTime = currentTime;
|
||||
video.currentTime = currentTime;
|
||||
},
|
||||
[mediaSet, audio, video]
|
||||
[mediaSet, audio, video, selection]
|
||||
);
|
||||
|
||||
const handlePlay = useCallback(() => {
|
||||
|
|
|
@ -71,30 +71,20 @@ export const Waveform: React.FC<Props> = ({
|
|||
setPositionPixels(null);
|
||||
return;
|
||||
}
|
||||
const logicalPixelsPerFrame =
|
||||
CanvasLogicalWidth / (viewport.end - viewport.start);
|
||||
const positionPixels = (frame - viewport.start) * logicalPixelsPerFrame;
|
||||
const pixelsPerFrame = CanvasLogicalWidth / (viewport.end - viewport.start);
|
||||
const positionPixels = (frame - viewport.start) * pixelsPerFrame;
|
||||
setPositionPixels(positionPixels);
|
||||
}, [mediaSet, position, viewport]);
|
||||
|
||||
// update selectedPixels on viewport change
|
||||
useEffect(() => {
|
||||
const start = frameToCanvasX(selectedFrames.start);
|
||||
const end = frameToCanvasX(selectedFrames.end);
|
||||
|
||||
// more verbose than it has to be to make TypeScript happy
|
||||
if (start == null && end == null) {
|
||||
setSelectedPixels({ start: 0, end: 0 });
|
||||
} else if (start == null && end != null) {
|
||||
setSelectedPixels({ start: 0, end: end });
|
||||
} else if (start != null && end == null) {
|
||||
setSelectedPixels({ start: 0, end: CanvasLogicalWidth });
|
||||
} else if (start != null && end != null) {
|
||||
setSelectedPixels({ start, end });
|
||||
} else {
|
||||
console.error('unreachable');
|
||||
}
|
||||
}, [viewport]);
|
||||
const start = Math.max(frameToCanvasX(selectedFrames.start), 0);
|
||||
const end = Math.min(
|
||||
frameToCanvasX(selectedFrames.end),
|
||||
CanvasLogicalWidth
|
||||
);
|
||||
setSelectedPixels({ start, end });
|
||||
}, [viewport, selectedFrames]);
|
||||
|
||||
// handlers
|
||||
|
||||
|
@ -112,26 +102,18 @@ export const Waveform: React.FC<Props> = ({
|
|||
setSelectedFrames(selectedFrames);
|
||||
onSelectionChange(selectedFrames);
|
||||
},
|
||||
[viewport]
|
||||
[viewport, selectedFrames]
|
||||
);
|
||||
|
||||
// helpers
|
||||
|
||||
const frameToCanvasX = useCallback(
|
||||
(frame: number): number | null => {
|
||||
if (mediaSet == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (frame < viewport.start || frame > viewport.end) {
|
||||
return null;
|
||||
}
|
||||
|
||||
(frame: number): number => {
|
||||
const pixelsPerFrame =
|
||||
CanvasLogicalWidth / (viewport.end - viewport.start);
|
||||
return (frame - viewport.start) * pixelsPerFrame;
|
||||
return Math.round((frame - viewport.start) * pixelsPerFrame);
|
||||
},
|
||||
[mediaSet, viewport]
|
||||
[viewport]
|
||||
);
|
||||
|
||||
// render component
|
||||
|
|
Loading…
Reference in New Issue