57 lines
1.6 KiB
TypeScript
57 lines
1.6 KiB
TypeScript
import { MouseEvent } from 'react';
|
|
import { Frames } from './App';
|
|
|
|
// TODO: pass CanvasLogicalWidth as an argument instead.
|
|
import { CanvasLogicalWidth } from './Waveform';
|
|
|
|
interface Point {
|
|
x: number;
|
|
y: number;
|
|
}
|
|
|
|
// TODO: add tests
|
|
export const mouseEventToCanvasX = (
|
|
evt: MouseEvent<HTMLCanvasElement>
|
|
): number => {
|
|
const rect = evt.currentTarget.getBoundingClientRect();
|
|
const elementX = evt.clientX - rect.left;
|
|
return (elementX * CanvasLogicalWidth) / rect.width;
|
|
};
|
|
|
|
// TODO: add tests
|
|
export const mouseEventToCanvasPoint = (
|
|
evt: MouseEvent<HTMLCanvasElement>
|
|
): Point => {
|
|
const rect = evt.currentTarget.getBoundingClientRect();
|
|
const elementX = evt.clientX - rect.left;
|
|
const elementY = evt.clientY - rect.top;
|
|
|
|
return {
|
|
x: (elementX * evt.currentTarget.width) / rect.width,
|
|
y: (elementY * evt.currentTarget.height) / rect.height,
|
|
};
|
|
};
|
|
|
|
// TODO: add tests
|
|
export const canvasXToFrame = (x: number, numFrames: number): number => {
|
|
return Math.floor((x / CanvasLogicalWidth) * numFrames);
|
|
};
|
|
|
|
// TODO: add tests
|
|
// secsToCanvasX returns the logical x coordinate for a given position
|
|
// marker. It is null if the marker is outside of the current viewport.
|
|
export const secsToCanvasX = (
|
|
secs: number,
|
|
sampleRate: number,
|
|
viewport: Frames
|
|
): number | null => {
|
|
const frame = Math.round(secs * sampleRate);
|
|
if (frame < viewport.start || frame > viewport.end) {
|
|
return null;
|
|
}
|
|
|
|
const logicalPixelsPerFrame =
|
|
CanvasLogicalWidth / (viewport.end - viewport.start);
|
|
return (frame - viewport.start) * logicalPixelsPerFrame;
|
|
};
|