Edit: IN/OUT marker triangles + Postavi IN/OUT buttons
User feedback: Workflow is - click + Enter sets a marker triangle, then button moves the red handle to that triangle. Triangle near LEFT handle = IN candidate (green), near RIGHT = OUT candidate (red). Visual: - Green triangle (▼) above trim bar = IN candidate position - Red triangle (▼) above trim bar = OUT candidate position - White line (playhead) = current video position (moves during playback) - Red handles (existing) = actual clip start/end Workflow: 1. Click on waveform → white playhead jumps there 2. Press Enter → playhead starts moving (plays) ALSO: triangle gets placed at current position - If position closer to LEFT handle → green IN triangle - If position closer to RIGHT handle → red OUT triangle 3. Listen, decide 'this is the right spot' 4. Click ▼ Postavi IN button → red LEFT handle jumps to green triangle (or ▼ Postavi OUT for right handle) 5. Now red handle and triangle are aligned = clip boundary committed Triangles persist until next play press (= next candidate). Buttons styled with matching color (green for IN, red for OUT).
This commit is contained in:
parent
4376f7529f
commit
5d817c586b
@ -1085,6 +1085,16 @@
|
|||||||
<div style="width:4px; height:32px; background:#fff; border-radius:2px;"></div>
|
<div style="width:4px; height:32px; background:#fff; border-radius:2px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- IN marker (zelen trikotnik — kjer si pritisnil play blizu levega handle) -->
|
||||||
|
<div id="marker-in" style="position:absolute; top:-14px; left:calc(${pctOfStr(startInit, videoDuration)}% - 7px); width:14px; height:14px; z-index:5; pointer-events:none;">
|
||||||
|
<div style="width:0; height:0; border-left:7px solid transparent; border-right:7px solid transparent; border-top:14px solid #4ade80; filter:drop-shadow(0 0 4px #4ade80);"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- OUT marker (rdeč trikotnik — kjer si pritisnil play blizu desnega handle) -->
|
||||||
|
<div id="marker-out" style="position:absolute; top:-14px; left:calc(${pctOfStr(endInit, videoDuration)}% - 7px); width:14px; height:14px; z-index:5; pointer-events:none;">
|
||||||
|
<div style="width:0; height:0; border-left:7px solid transparent; border-right:7px solid transparent; border-top:14px solid #ff6b6b; filter:drop-shadow(0 0 4px #ff6b6b);"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Playhead (bel črtnik — "tracker") -->
|
<!-- Playhead (bel črtnik — "tracker") -->
|
||||||
<div id="trim-playhead" style="position:absolute; top:-6px; bottom:-6px; left:0%; width:2px; background:#fff; z-index:2; pointer-events:none; opacity:1; box-shadow:0 0 8px rgba(255,255,255,0.8);">
|
<div id="trim-playhead" style="position:absolute; top:-6px; bottom:-6px; left:0%; width:2px; background:#fff; z-index:2; pointer-events:none; opacity:1; box-shadow:0 0 8px rgba(255,255,255,0.8);">
|
||||||
<!-- Trikotnik na vrhu -->
|
<!-- Trikotnik na vrhu -->
|
||||||
@ -1099,7 +1109,7 @@
|
|||||||
|
|
||||||
<!-- Hint -->
|
<!-- Hint -->
|
||||||
<div style="font-size:11px; color:var(--muted); margin-top:6px; text-align:center;">
|
<div style="font-size:11px; color:var(--muted); margin-top:6px; text-align:center;">
|
||||||
← Povleci rdeče ročaje · Klik na valove = skoči (bel črtnik) · Enter = play/pause od pozicije
|
← Klik = bel črtnik · Enter = play (postavi ▼ trikotnik kjer si bil) · "Postavi IN/OUT" = handle skoči na trikotnik
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1112,8 +1122,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div style="display:flex; gap:8px;">
|
<div style="display:flex; gap:8px;">
|
||||||
<button class="primary" id="preview-btn" onclick="previewSelection()" title="Predvajaj točno označen del" style="background:var(--accent); padding:8px 16px;">▶ Predvajaj odsek</button>
|
<button class="primary" id="preview-btn" onclick="previewSelection()" title="Predvajaj točno označen del" style="background:var(--accent); padding:8px 16px;">▶ Predvajaj odsek</button>
|
||||||
<button class="small ghost" onclick="seekEditVideo('start')" title="Skoči na začetek">⤴ Začetek</button>
|
<button class="small ghost" onclick="seekEditVideo('start')" title="Premakni levi handle na zelen trikotnik" style="border-color:#4ade80; color:#4ade80;">▼ Postavi IN</button>
|
||||||
<button class="small ghost" onclick="seekEditVideo('end')" title="Skoči na konec">↪ Konec</button>
|
<button class="small ghost" onclick="seekEditVideo('end')" title="Premakni desni handle na rdeč trikotnik" style="border-color:#ff6b6b; color:#ff6b6b;">▼ Postavi OUT</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="preview-status" style="margin-top:6px; font-size:12px; color:var(--muted); text-align:right;"></div>
|
<div id="preview-status" style="margin-top:6px; font-size:12px; color:var(--muted); text-align:right;"></div>
|
||||||
@ -1154,6 +1164,17 @@
|
|||||||
let trimEnd = endInit;
|
let trimEnd = endInit;
|
||||||
let dragging = null; // 'left' / 'right' / null
|
let dragging = null; // 'left' / 'right' / null
|
||||||
|
|
||||||
|
// Marker state — kje je bil zadnji play (loči levi/desni)
|
||||||
|
let markerInTime = startInit; // pozicija zelenega trikotnika
|
||||||
|
let markerOutTime = endInit; // pozicija rdečega trikotnika
|
||||||
|
const markerInEl = document.getElementById("marker-in");
|
||||||
|
const markerOutEl = document.getElementById("marker-out");
|
||||||
|
|
||||||
|
function renderMarkers() {
|
||||||
|
if (markerInEl) markerInEl.style.left = `calc(${pctOfStr(markerInTime, videoDuration)}% - 7px)`;
|
||||||
|
if (markerOutEl) markerOutEl.style.left = `calc(${pctOfStr(markerOutTime, videoDuration)}% - 7px)`;
|
||||||
|
}
|
||||||
|
|
||||||
function pctOf(t) {
|
function pctOf(t) {
|
||||||
return (t / videoDuration) * 100;
|
return (t / videoDuration) * 100;
|
||||||
}
|
}
|
||||||
@ -1269,6 +1290,7 @@
|
|||||||
trimScroll.scrollLeft = Math.max(0, scrollTarget);
|
trimScroll.scrollLeft = Math.max(0, scrollTarget);
|
||||||
}
|
}
|
||||||
renderTrim();
|
renderTrim();
|
||||||
|
renderMarkers();
|
||||||
}, 50);
|
}, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1288,6 +1310,17 @@
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (video) {
|
if (video) {
|
||||||
if (video.paused) {
|
if (video.paused) {
|
||||||
|
// Pred play-em: postavi trikotnik na trenutno pozicijo
|
||||||
|
// Loči levi/desni glede na bližino handle-jev
|
||||||
|
const t = video.currentTime;
|
||||||
|
const distToLeft = Math.abs(t - trimStart);
|
||||||
|
const distToRight = Math.abs(t - trimEnd);
|
||||||
|
if (distToLeft <= distToRight) {
|
||||||
|
markerInTime = t;
|
||||||
|
} else {
|
||||||
|
markerOutTime = t;
|
||||||
|
}
|
||||||
|
renderMarkers();
|
||||||
video.play().catch(() => {});
|
video.play().catch(() => {});
|
||||||
} else {
|
} else {
|
||||||
video.pause();
|
video.pause();
|
||||||
@ -1317,12 +1350,25 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "⤴ Začetek" gumb = premakni LEVI handle na zelen trikotnik (commit IN)
|
||||||
|
// "↪ Konec" gumb = premakni DESNI handle na rdeč trikotnik (commit OUT)
|
||||||
window.seekEditVideo = function(which) {
|
window.seekEditVideo = function(which) {
|
||||||
if (!video) return;
|
if (!video) return;
|
||||||
const t = which === "start" ? trimStart : trimEnd;
|
|
||||||
video.currentTime = t;
|
|
||||||
if (which === "start") {
|
if (which === "start") {
|
||||||
video.play();
|
// Commit IN: levi handle skoči na zelen trikotnik
|
||||||
|
if (markerInTime < trimEnd - 1) {
|
||||||
|
trimStart = markerInTime;
|
||||||
|
renderTrim();
|
||||||
|
// Skoči na to pozicijo
|
||||||
|
video.currentTime = trimStart;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Commit OUT: desni handle skoči na rdeč trikotnik
|
||||||
|
if (markerOutTime > trimStart + 1) {
|
||||||
|
trimEnd = markerOutTime;
|
||||||
|
renderTrim();
|
||||||
|
video.currentTime = trimEnd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1400,6 +1446,7 @@
|
|||||||
const ro = new ResizeObserver(() => {
|
const ro = new ResizeObserver(() => {
|
||||||
renderTrim();
|
renderTrim();
|
||||||
renderPlayhead();
|
renderPlayhead();
|
||||||
|
renderMarkers();
|
||||||
});
|
});
|
||||||
ro.observe(trimBar);
|
ro.observe(trimBar);
|
||||||
|
|
||||||
@ -1408,6 +1455,7 @@
|
|||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
renderTrim();
|
renderTrim();
|
||||||
renderPlayhead();
|
renderPlayhead();
|
||||||
|
renderMarkers();
|
||||||
// Nastavi 1x kot aktiven gumb
|
// Nastavi 1x kot aktiven gumb
|
||||||
applyZoom(1);
|
applyZoom(1);
|
||||||
console.log("[EditModal] after renderTrim", {
|
console.log("[EditModal] after renderTrim", {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user