feat: Add visual scrubber to video editor
Task #69 completed by ClaudeQueue ClaudeQueue
This commit is contained in:
@@ -745,6 +745,11 @@ function openVideoEditor(source) {
|
||||
body.className = 'video-editor';
|
||||
body.innerHTML = `
|
||||
<p class="ve-intro">Mark the parts to <strong>remove</strong>. Everything else is kept and saved as a new offline video.</p>
|
||||
<div class="ve-scrubber-track">
|
||||
<div class="ve-scrubber-bar"></div>
|
||||
<div class="ve-marker ve-marker-a"></div>
|
||||
<div class="ve-marker ve-marker-b"></div>
|
||||
</div>
|
||||
<div class="ve-add-row">
|
||||
<label>From <input type="text" class="ve-from" placeholder="0:30" inputmode="numeric" /></label>
|
||||
<label>To <input type="text" class="ve-to" placeholder="1:15" inputmode="numeric" /></label>
|
||||
@@ -762,8 +767,33 @@ function openVideoEditor(source) {
|
||||
const cutsEl = body.querySelector('.ve-cuts');
|
||||
const titleEl = body.querySelector('.ve-title');
|
||||
const sumEl = body.querySelector('.ve-summary');
|
||||
const trackEl = body.querySelector('.ve-scrubber-track');
|
||||
const markerA = body.querySelector('.ve-marker-a');
|
||||
const markerB = body.querySelector('.ve-marker-b');
|
||||
|
||||
titleEl.value = (source.title || 'Video') + ' (edit)';
|
||||
|
||||
// Update markers based on duration
|
||||
function updateScrubber() {
|
||||
const a = VideoEdit.parseTime(fromEl.value);
|
||||
const b = VideoEdit.parseTime(toEl.value);
|
||||
|
||||
if (a !== null) markerA.style.left = (a / duration * 100) + '%';
|
||||
if (b !== null) markerB.style.left = (b / duration * 100) + '%';
|
||||
}
|
||||
|
||||
trackEl.onclick = (e) => {
|
||||
const rect = trackEl.getBoundingClientRect();
|
||||
const percent = (e.clientX - rect.left) / rect.width;
|
||||
const time = Math.round(percent * duration);
|
||||
if (!fromEl.value) fromEl.value = VideoEdit.fmtTime(time);
|
||||
else if (!toEl.value) toEl.value = VideoEdit.fmtTime(time);
|
||||
updateScrubber();
|
||||
};
|
||||
|
||||
fromEl.oninput = updateScrubber;
|
||||
toEl.oninput = updateScrubber;
|
||||
|
||||
function showErr(msg) {
|
||||
errEl.textContent = msg;
|
||||
errEl.hidden = !msg;
|
||||
|
||||
@@ -2259,3 +2259,29 @@ input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.25); }
|
||||
box-shadow: 0 2px 6px -2px var(--accent-glow);
|
||||
}
|
||||
.saved-card.custom .thumb { position: relative; }
|
||||
|
||||
/* Video Editor Scrubber */
|
||||
.ve-scrubber-track {
|
||||
height: 30px;
|
||||
background: var(--bg-3);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm);
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.ve-scrubber-bar {
|
||||
height: 100%;
|
||||
background: var(--bg-2);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
.ve-marker {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
background: var(--accent);
|
||||
pointer-events: none;
|
||||
}
|
||||
.ve-marker-a { left: 0; }
|
||||
.ve-marker-b { right: 0; }
|
||||
|
||||
Reference in New Issue
Block a user