Make position marker viewport-aware

This commit is contained in:
Rob Watson 2021-09-27 21:19:29 +02:00
parent 8cade215af
commit f237823b65
2 changed files with 24 additions and 22 deletions

View File

@ -2,11 +2,7 @@ import { useEffect, useState, useRef, MouseEvent } from 'react';
import { Waveform as WaveformOverview } from './Waveform/Overview';
import { Thumbnails } from './Waveform/Thumbnails';
import { Canvas as WaveformCanvas } from './Waveform/Canvas';
import {
secsToCanvasX,
canvasXToFrame,
mouseEventToCanvasX,
} from './Waveform/Helpers';
import { canvasXToFrame, mouseEventToCanvasX } from './Waveform/Helpers';
type Props = {
audioContext: AudioContext;
@ -65,6 +61,25 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
// TODO: error handling
const videoID = new URLSearchParams(window.location.search).get('video_id');
// helpers
// secsToCanvasX returns the logical x coordinate for a given position
// marker. It is null if the marker is outside of the current viewport.
const secsToCanvasX = (secs: number): number | null => {
if (mediaSet == null) {
return null;
}
const frame = secs * mediaSet.audio.sampleRate;
if (frame < zoomSettings.startFrame || frame > zoomSettings.endFrame) {
return null;
}
const logicalPixelsPerFrame =
CanvasLogicalWidth / (zoomSettings.endFrame - zoomSettings.startFrame);
return (frame - zoomSettings.startFrame) * logicalPixelsPerFrame;
};
// effects
// setup player on page load:
@ -180,11 +195,10 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
return;
}
const x = secsToCanvasX(
currentTime,
mediaSet.audio.sampleRate,
mediaSet.audio.frames
);
const x = secsToCanvasX(currentTime);
if (x == null) {
return;
}
ctx.strokeStyle = 'red';
ctx.beginPath();
@ -279,7 +293,6 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
};
const handleSelectionChange = (selection: Selection) => {
console.log('in handleSelectionChange handler');
if (mediaSet == null) {
return;
}

View File

@ -5,7 +5,6 @@ import { MouseEvent } from 'react';
export const mouseEventToCanvasX = (
evt: MouseEvent<HTMLCanvasElement>
): number => {
// TODO: use offsetX/offsetY?
const rect = evt.currentTarget.getBoundingClientRect();
const elementX = evt.clientX - rect.left;
return (elementX * CanvasLogicalWidth) / rect.width;
@ -15,13 +14,3 @@ export const mouseEventToCanvasX = (
export const canvasXToFrame = (x: number, numFrames: number): number => {
return Math.floor((x / CanvasLogicalWidth) * numFrames);
};
// TODO: add tests
export const secsToCanvasX = (
secs: number,
sampleRate: number,
numFrames: number
): number => {
const duration = numFrames / sampleRate;
return Math.floor(CanvasLogicalWidth * (secs / duration));
};