Rename spectrogram references to waveform throughout codebase
This commit is contained in:
94
app.js
94
app.js
@@ -5,8 +5,8 @@ const durationEl = document.getElementById("duration");
|
||||
const activeSpeakerEl = document.getElementById("activeSpeaker");
|
||||
const speakerListEl = document.getElementById("speakerList");
|
||||
const spaceCanvas = document.getElementById("spaceCanvas");
|
||||
const spectrogramCanvas = document.getElementById("spectrogramCanvas");
|
||||
const spectrogramOverlay = document.getElementById("spectrogramOverlay");
|
||||
const waveformCanvas = document.getElementById("waveformCanvas");
|
||||
const waveformOverlay = document.getElementById("waveformOverlay");
|
||||
const transcriptPanel = document.getElementById("transcriptPanel");
|
||||
const configToggle = document.getElementById("configToggle");
|
||||
const configPanel = document.getElementById("configPanel");
|
||||
@@ -18,14 +18,14 @@ const sizeSelect = document.getElementById("sizeSelect");
|
||||
const waveformEmbeddedCheckbox = document.getElementById("waveformEmbedded");
|
||||
const stageEl = document.querySelector(".stage");
|
||||
const appEl = document.querySelector(".app");
|
||||
const spectrogramWrap = document.querySelector(".spectrogram-wrap");
|
||||
const waveformWrap = document.querySelector(".waveform-wrap");
|
||||
const embeddedWaveform = document.getElementById("embeddedWaveform");
|
||||
const embeddedWaveformCanvas = document.getElementById("embeddedWaveformCanvas");
|
||||
const embeddedWaveformOverlay = document.getElementById("embeddedWaveformOverlay");
|
||||
|
||||
const spaceCtx = spaceCanvas.getContext("2d");
|
||||
const spectrogramCtx = spectrogramCanvas.getContext("2d");
|
||||
const spectrogramOverlayCtx = spectrogramOverlay.getContext("2d");
|
||||
const waveformCtx = waveformCanvas.getContext("2d");
|
||||
const waveformOverlayCtx = waveformOverlay.getContext("2d");
|
||||
const embeddedWaveformCtx = embeddedWaveformCanvas ? embeddedWaveformCanvas.getContext("2d") : null;
|
||||
const embeddedWaveformOverlayCtx = embeddedWaveformOverlay ? embeddedWaveformOverlay.getContext("2d") : null;
|
||||
|
||||
@@ -75,7 +75,6 @@ const state = {
|
||||
waveformReady: false,
|
||||
waveformLoading: false,
|
||||
waveformEmbedded: false,
|
||||
stars: [],
|
||||
spaceSize: { width: 0, height: 0 },
|
||||
waveformSize: { width: 0, height: 0 },
|
||||
transcriptRows: CONFIG.transcript.rows,
|
||||
@@ -398,8 +397,8 @@ function resizeCanvas(canvas, ctx) {
|
||||
|
||||
function resizeAll() {
|
||||
resizeCanvas(spaceCanvas, spaceCtx);
|
||||
resizeCanvas(spectrogramCanvas, spectrogramCtx);
|
||||
resizeCanvas(spectrogramOverlay, spectrogramOverlayCtx);
|
||||
resizeCanvas(waveformCanvas, waveformCtx);
|
||||
resizeCanvas(waveformOverlay, waveformOverlayCtx);
|
||||
if (embeddedWaveformCanvas && embeddedWaveformCtx) {
|
||||
resizeCanvas(embeddedWaveformCanvas, embeddedWaveformCtx);
|
||||
}
|
||||
@@ -409,13 +408,12 @@ function resizeAll() {
|
||||
const { width, height } = spaceCanvas.getBoundingClientRect();
|
||||
if (width > 0 && height > 0 && (width !== state.spaceSize.width || height !== state.spaceSize.height)) {
|
||||
state.spaceSize = { width, height };
|
||||
state.stars = seedStars(width, height);
|
||||
layoutSpeakers();
|
||||
}
|
||||
const specRect = spectrogramCanvas.getBoundingClientRect();
|
||||
if (specRect.width > 0 && specRect.height > 0) {
|
||||
if (specRect.width !== state.waveformSize.width || specRect.height !== state.waveformSize.height) {
|
||||
state.waveformSize = { width: specRect.width, height: specRect.height };
|
||||
const waveformRect = waveformCanvas.getBoundingClientRect();
|
||||
if (waveformRect.width > 0 && waveformRect.height > 0) {
|
||||
if (waveformRect.width !== state.waveformSize.width || waveformRect.height !== state.waveformSize.height) {
|
||||
state.waveformSize = { width: waveformRect.width, height: waveformRect.height };
|
||||
}
|
||||
}
|
||||
if (state.waveformReady && state.waveformData) {
|
||||
@@ -423,20 +421,6 @@ function resizeAll() {
|
||||
}
|
||||
}
|
||||
|
||||
function seedStars(width, height) {
|
||||
const stars = [];
|
||||
const count = Math.floor((width * height) / 5500);
|
||||
for (let i = 0; i < count; i += 1) {
|
||||
stars.push({
|
||||
x: Math.random() * width,
|
||||
y: Math.random() * height,
|
||||
radius: Math.random() * 1.8 + 0.2,
|
||||
alpha: Math.random() * 0.7 + 0.2,
|
||||
});
|
||||
}
|
||||
return stars;
|
||||
}
|
||||
|
||||
function renderSpace(timeMs) {
|
||||
const { width, height } = spaceCanvas.getBoundingClientRect();
|
||||
spaceCtx.clearRect(0, 0, width, height);
|
||||
@@ -484,8 +468,8 @@ function renderSpace(timeMs) {
|
||||
}
|
||||
|
||||
function updatePlayhead() {
|
||||
const { width, height } = spectrogramOverlay.getBoundingClientRect();
|
||||
spectrogramOverlayCtx.clearRect(0, 0, width, height);
|
||||
const { width, height } = waveformOverlay.getBoundingClientRect();
|
||||
waveformOverlayCtx.clearRect(0, 0, width, height);
|
||||
|
||||
// Also update embedded waveform overlay
|
||||
if (embeddedWaveformOverlay && embeddedWaveformOverlayCtx) {
|
||||
@@ -496,12 +480,12 @@ function updatePlayhead() {
|
||||
if (!Number.isFinite(audio.duration) || audio.duration <= 0) return;
|
||||
const progress = audio.currentTime / audio.duration;
|
||||
const x = progress * width;
|
||||
spectrogramOverlayCtx.strokeStyle = "#f4d35e";
|
||||
spectrogramOverlayCtx.lineWidth = 2;
|
||||
spectrogramOverlayCtx.beginPath();
|
||||
spectrogramOverlayCtx.moveTo(x, 0);
|
||||
spectrogramOverlayCtx.lineTo(x, height);
|
||||
spectrogramOverlayCtx.stroke();
|
||||
waveformOverlayCtx.strokeStyle = "#f4d35e";
|
||||
waveformOverlayCtx.lineWidth = 2;
|
||||
waveformOverlayCtx.beginPath();
|
||||
waveformOverlayCtx.moveTo(x, 0);
|
||||
waveformOverlayCtx.lineTo(x, height);
|
||||
waveformOverlayCtx.stroke();
|
||||
|
||||
// Draw playhead on embedded waveform overlay
|
||||
if (embeddedWaveformOverlay && embeddedWaveformOverlayCtx) {
|
||||
@@ -586,9 +570,9 @@ function drawWaveformOnCanvas(ctx, peaks, width, height, duration, intervals, sp
|
||||
}
|
||||
|
||||
function drawWaveform(peaks) {
|
||||
const { width, height } = spectrogramCanvas.getBoundingClientRect();
|
||||
const { width, height } = waveformCanvas.getBoundingClientRect();
|
||||
const duration = Number.isFinite(audio.duration) ? audio.duration : 0;
|
||||
drawWaveformOnCanvas(spectrogramCtx, peaks, width, height, duration, state.intervals, state.speakerMap);
|
||||
drawWaveformOnCanvas(waveformCtx, peaks, width, height, duration, state.intervals, state.speakerMap);
|
||||
|
||||
// Also draw on embedded waveform canvas
|
||||
if (embeddedWaveformCanvas && embeddedWaveformCtx) {
|
||||
@@ -601,8 +585,8 @@ async function loadWaveformData() {
|
||||
if (state.waveformLoading || state.waveformReady) return;
|
||||
|
||||
state.waveformLoading = true;
|
||||
if (spectrogramWrap) {
|
||||
spectrogramWrap.classList.add("loading");
|
||||
if (waveformWrap) {
|
||||
waveformWrap.classList.add("loading");
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -618,21 +602,21 @@ async function loadWaveformData() {
|
||||
console.info("Generate waveform data using: node scripts/generate-waveform.js <audio-file>");
|
||||
} finally {
|
||||
state.waveformLoading = false;
|
||||
if (spectrogramWrap) {
|
||||
spectrogramWrap.classList.remove("loading");
|
||||
if (waveformWrap) {
|
||||
waveformWrap.classList.remove("loading");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function attachScrubHandlers() {
|
||||
if (!spectrogramWrap) return;
|
||||
if (!waveformWrap) return;
|
||||
let wasPlaying = false;
|
||||
|
||||
const onDown = (event) => {
|
||||
state.playheadDragging = true;
|
||||
wasPlaying = !audio.paused;
|
||||
if (event.pointerId != null) {
|
||||
spectrogramWrap.setPointerCapture(event.pointerId);
|
||||
waveformWrap.setPointerCapture(event.pointerId);
|
||||
}
|
||||
scrubToEvent(event);
|
||||
};
|
||||
@@ -646,7 +630,7 @@ function attachScrubHandlers() {
|
||||
const wasDragging = state.playheadDragging;
|
||||
state.playheadDragging = false;
|
||||
if (event.pointerId != null) {
|
||||
spectrogramWrap.releasePointerCapture(event.pointerId);
|
||||
waveformWrap.releasePointerCapture(event.pointerId);
|
||||
}
|
||||
// Start playback on any timeline click/scrub
|
||||
if (wasDragging) {
|
||||
@@ -654,10 +638,10 @@ function attachScrubHandlers() {
|
||||
}
|
||||
};
|
||||
|
||||
spectrogramWrap.addEventListener("pointerdown", onDown);
|
||||
spectrogramWrap.addEventListener("pointermove", onMove);
|
||||
spectrogramWrap.addEventListener("pointerup", onUp);
|
||||
spectrogramWrap.addEventListener("pointerleave", () => {
|
||||
waveformWrap.addEventListener("pointerdown", onDown);
|
||||
waveformWrap.addEventListener("pointermove", onMove);
|
||||
waveformWrap.addEventListener("pointerup", onUp);
|
||||
waveformWrap.addEventListener("pointerleave", () => {
|
||||
const wasDragging = state.playheadDragging;
|
||||
state.playheadDragging = false;
|
||||
if (wasDragging && wasPlaying) {
|
||||
@@ -665,19 +649,19 @@ function attachScrubHandlers() {
|
||||
}
|
||||
});
|
||||
|
||||
spectrogramWrap.addEventListener("mousedown", onDown);
|
||||
waveformWrap.addEventListener("mousedown", onDown);
|
||||
window.addEventListener("mousemove", onMove);
|
||||
window.addEventListener("mouseup", onUp);
|
||||
|
||||
spectrogramWrap.addEventListener("touchstart", (event) => {
|
||||
waveformWrap.addEventListener("touchstart", (event) => {
|
||||
event.preventDefault();
|
||||
onDown(event.touches[0]);
|
||||
}, { passive: false });
|
||||
spectrogramWrap.addEventListener("touchmove", (event) => {
|
||||
waveformWrap.addEventListener("touchmove", (event) => {
|
||||
event.preventDefault();
|
||||
onMove(event.touches[0]);
|
||||
}, { passive: false });
|
||||
spectrogramWrap.addEventListener("touchend", (event) => {
|
||||
waveformWrap.addEventListener("touchend", (event) => {
|
||||
event.preventDefault();
|
||||
onUp(event.changedTouches[0] || event.touches[0]);
|
||||
}, { passive: false });
|
||||
@@ -685,8 +669,8 @@ function attachScrubHandlers() {
|
||||
|
||||
function scrubToEvent(event) {
|
||||
if (!Number.isFinite(audio.duration)) return;
|
||||
if (!spectrogramWrap) return;
|
||||
const rect = spectrogramWrap.getBoundingClientRect();
|
||||
if (!waveformWrap) return;
|
||||
const rect = waveformWrap.getBoundingClientRect();
|
||||
const percent = Math.min(1, Math.max(0, (event.clientX - rect.left) / rect.width));
|
||||
audio.currentTime = percent * audio.duration;
|
||||
}
|
||||
@@ -805,7 +789,7 @@ async function init() {
|
||||
window.addEventListener("load", () => requestAnimationFrame(resizeAll));
|
||||
const resizeObserver = new ResizeObserver(() => resizeAll());
|
||||
if (stageEl) resizeObserver.observe(stageEl);
|
||||
if (spectrogramWrap) resizeObserver.observe(spectrogramWrap);
|
||||
if (waveformWrap) resizeObserver.observe(waveformWrap);
|
||||
if (embeddedWaveform) resizeObserver.observe(embeddedWaveform);
|
||||
attachScrubHandlers();
|
||||
attachEmbeddedScrubHandlers();
|
||||
|
||||
10
index.html
10
index.html
@@ -60,8 +60,8 @@
|
||||
<div class="speaker-list" id="speakerList"></div>
|
||||
</div>
|
||||
<div class="embedded-waveform" id="embeddedWaveform">
|
||||
<canvas id="embeddedWaveformCanvas" class="spectrogram"></canvas>
|
||||
<canvas id="embeddedWaveformOverlay" class="spectrogram overlay"></canvas>
|
||||
<canvas id="embeddedWaveformCanvas" class="waveform"></canvas>
|
||||
<canvas id="embeddedWaveformOverlay" class="waveform overlay"></canvas>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -74,9 +74,9 @@
|
||||
<span class="time-divider">/</span>
|
||||
<span id="duration">0:00</span>
|
||||
</div>
|
||||
<div class="spectrogram-wrap">
|
||||
<canvas id="spectrogramCanvas" class="spectrogram"></canvas>
|
||||
<canvas id="spectrogramOverlay" class="spectrogram overlay"></canvas>
|
||||
<div class="waveform-wrap">
|
||||
<canvas id="waveformCanvas" class="waveform"></canvas>
|
||||
<canvas id="waveformOverlay" class="waveform overlay"></canvas>
|
||||
</div>
|
||||
<div class="scrub-hint">Drag anywhere on the waveform to scrub.</div>
|
||||
</section>
|
||||
|
||||
12
styles.css
12
styles.css
@@ -185,7 +185,7 @@ body {
|
||||
background: rgba(5, 7, 11, 0.8);
|
||||
}
|
||||
|
||||
.spectrogram-wrap {
|
||||
.waveform-wrap {
|
||||
position: relative;
|
||||
height: 50px;
|
||||
border-radius: 0;
|
||||
@@ -197,14 +197,14 @@ body {
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.spectrogram {
|
||||
.waveform {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.spectrogram.overlay {
|
||||
.waveform.overlay {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ body {
|
||||
bottom: calc(25% + 28px);
|
||||
}
|
||||
|
||||
.app.waveform-embedded .transport .spectrogram-wrap {
|
||||
.app.waveform-embedded .transport .waveform-wrap {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -333,7 +333,7 @@ body {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.spectrogram-wrap.loading::before {
|
||||
.waveform-wrap.loading::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
@@ -347,7 +347,7 @@ body {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.spectrogram-wrap.loading::after {
|
||||
.waveform-wrap.loading::after {
|
||||
content: "Loading waveform...";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
|
||||
Reference in New Issue
Block a user