Make position marker viewport-aware
This commit is contained in:
parent
8cade215af
commit
f237823b65
|
@ -2,11 +2,7 @@ import { useEffect, useState, useRef, MouseEvent } from 'react';
|
||||||
import { Waveform as WaveformOverview } from './Waveform/Overview';
|
import { Waveform as WaveformOverview } from './Waveform/Overview';
|
||||||
import { Thumbnails } from './Waveform/Thumbnails';
|
import { Thumbnails } from './Waveform/Thumbnails';
|
||||||
import { Canvas as WaveformCanvas } from './Waveform/Canvas';
|
import { Canvas as WaveformCanvas } from './Waveform/Canvas';
|
||||||
import {
|
import { canvasXToFrame, mouseEventToCanvasX } from './Waveform/Helpers';
|
||||||
secsToCanvasX,
|
|
||||||
canvasXToFrame,
|
|
||||||
mouseEventToCanvasX,
|
|
||||||
} from './Waveform/Helpers';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
audioContext: AudioContext;
|
audioContext: AudioContext;
|
||||||
|
@ -65,6 +61,25 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
||||||
// TODO: error handling
|
// TODO: error handling
|
||||||
const videoID = new URLSearchParams(window.location.search).get('video_id');
|
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
|
// effects
|
||||||
|
|
||||||
// setup player on page load:
|
// setup player on page load:
|
||||||
|
@ -180,11 +195,10 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const x = secsToCanvasX(
|
const x = secsToCanvasX(currentTime);
|
||||||
currentTime,
|
if (x == null) {
|
||||||
mediaSet.audio.sampleRate,
|
return;
|
||||||
mediaSet.audio.frames
|
}
|
||||||
);
|
|
||||||
|
|
||||||
ctx.strokeStyle = 'red';
|
ctx.strokeStyle = 'red';
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
|
@ -279,7 +293,6 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectionChange = (selection: Selection) => {
|
const handleSelectionChange = (selection: Selection) => {
|
||||||
console.log('in handleSelectionChange handler');
|
|
||||||
if (mediaSet == null) {
|
if (mediaSet == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { MouseEvent } from 'react';
|
||||||
export const mouseEventToCanvasX = (
|
export const mouseEventToCanvasX = (
|
||||||
evt: MouseEvent<HTMLCanvasElement>
|
evt: MouseEvent<HTMLCanvasElement>
|
||||||
): number => {
|
): number => {
|
||||||
// TODO: use offsetX/offsetY?
|
|
||||||
const rect = evt.currentTarget.getBoundingClientRect();
|
const rect = evt.currentTarget.getBoundingClientRect();
|
||||||
const elementX = evt.clientX - rect.left;
|
const elementX = evt.clientX - rect.left;
|
||||||
return (elementX * CanvasLogicalWidth) / rect.width;
|
return (elementX * CanvasLogicalWidth) / rect.width;
|
||||||
|
@ -15,13 +14,3 @@ export const mouseEventToCanvasX = (
|
||||||
export const canvasXToFrame = (x: number, numFrames: number): number => {
|
export const canvasXToFrame = (x: number, numFrames: number): number => {
|
||||||
return Math.floor((x / CanvasLogicalWidth) * numFrames);
|
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));
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue