diff --git a/app.js b/app.js index 1eae688..9d2ca97 100644 --- a/app.js +++ b/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 "); } 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(); diff --git a/index.html b/index.html index 20779b4..3cc52aa 100644 --- a/index.html +++ b/index.html @@ -60,8 +60,8 @@
- - + +
@@ -74,9 +74,9 @@ / 0:00 -
- - +
+ +
Drag anywhere on the waveform to scrub.
diff --git a/styles.css b/styles.css index 7c205e6..1325eb0 100644 --- a/styles.css +++ b/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;