From 47a114ce6ac175bbf308ea946119fa2db733db0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastjan=20Arti=C4=8D?= Date: Thu, 30 Apr 2026 12:37:06 +0000 Subject: [PATCH] Edit modal: zoom + play-from-position + Space toggle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User feedback: 1. 'Wave form je premajhen — zoom' 2. 'Ko nastavimo pozicijo, play od začetka — ne moremo predvajat od tam' NEW Zoom feature: - 5 zoom levels: 1x, 2x, 5x, 10x, 20x - Trim bar wrapped in scrollable container - On zoom: bar width grows to 100*N%, scroll auto-centers on trim region - Higher zoom = more pixels per second = micro-tuning possible (1x: 5px/s, 20x: 100px/s for 4min song) - Active zoom button highlighted accent red NEW Play-from-position: - Click on waveform/trim bar = playhead JUMPS THERE + auto-plays (was: just moved playhead, no play) - Space key = play/pause toggle from current position (works anywhere except in input fields) - '▶ Predvajaj odsek' still does start-to-end of selection - Cleanup keydown listener on modal close Waveform now rendered at 2400x72 (higher res) so zoom looks crisp. User can now: - Zoom 10x to see exact word boundaries in waveform - Click anywhere → instant play from there - Hit Space to toggle while watching --- templates/index.html | 128 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 103 insertions(+), 25 deletions(-) diff --git a/templates/index.html b/templates/index.html index 0c7344f..5761b16 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1054,30 +1054,44 @@
- -
- - - - -
- - -
-
+ +
+ Zoom: + + + + + + Klik na valove = skoči + predvaja · Space = play/pause +
+ + +
+ +
+ + + + +
+ + +
+
+
+ + +
+
+
+ + +
+ + +
0:00
+
${formatTime(videoDuration)}
- - -
-
-
- - -
- - -
0:00
-
${formatTime(videoDuration)}
@@ -1212,13 +1226,71 @@ document.addEventListener("mouseup", onPointerUp); document.addEventListener("touchend", onPointerUp); - // Click anywhere on trim bar = seek video + // Click anywhere on trim bar = seek + predvajaj OD TJE (ne od trim start) trimBar.addEventListener("click", (e) => { if (e.target === handleL || e.target === handleR || handleL.contains(e.target) || handleR.contains(e.target)) return; const t = timeFromPx(e.clientX); - if (video) video.currentTime = t; + if (video) { + video.currentTime = t; + video.play().catch(() => {}); + } }); + // ─── ZOOM logic ─── + let currentZoom = 1; + const trimScroll = document.getElementById("trim-scroll"); + + function applyZoom(zoom) { + currentZoom = zoom; + trimBar.style.width = (100 * zoom) + "%"; + trimBar.style.minWidth = (100 * zoom) + "%"; + // Aktiven gumb + document.querySelectorAll(".zoom-btn").forEach(b => { + if (parseInt(b.dataset.zoom) === zoom) { + b.style.background = "var(--accent)"; + b.style.color = "#fff"; + } else { + b.style.background = ""; + b.style.color = ""; + } + }); + // Auto-scroll na sredino trim region + setTimeout(() => { + if (trimScroll) { + const barWidth = trimBar.getBoundingClientRect().width; + const centerPct = ((trimStart + trimEnd) / 2) / videoDuration; + const scrollTarget = barWidth * centerPct - trimScroll.clientWidth / 2; + trimScroll.scrollLeft = Math.max(0, scrollTarget); + } + renderTrim(); + }, 50); + } + + document.querySelectorAll(".zoom-btn").forEach(btn => { + btn.addEventListener("click", () => { + applyZoom(parseInt(btn.dataset.zoom)); + }); + }); + + // Space tipka = play/pause od trenutne pozicije (brez resetiranja na trim start) + const spaceHandler = (e) => { + if (e.code === "Space" && e.target.tagName !== "INPUT" && e.target.tagName !== "TEXTAREA") { + e.preventDefault(); + if (video) { + if (video.paused) { + video.play().catch(() => {}); + } else { + video.pause(); + } + } + } + }; + document.addEventListener("keydown", spaceHandler); + // Cleanup ob zaprtju modala + overlay._cleanup = () => { + document.removeEventListener("keydown", spaceHandler); + }; + // Update playhead during playback + re-render če videoDuration manjkalo if (video) { video.addEventListener("timeupdate", renderPlayhead); @@ -1325,6 +1397,8 @@ requestAnimationFrame(() => { renderTrim(); renderPlayhead(); + // Nastavi 1x kot aktiven gumb + applyZoom(1); console.log("[EditModal] after renderTrim", { leftStyle: handleL.style.left, rightStyle: handleR.style.left, @@ -1433,6 +1507,10 @@ function closeModal() { const overlay = document.querySelector(".modal-overlay"); if (overlay) { + // Cleanup event listeners (npr. Space tipka) + if (typeof overlay._cleanup === "function") { + try { overlay._cleanup(); } catch (e) {} + } // Stop video before removing (prevents memory leak) const video = overlay.querySelector("video"); if (video) {