diff --git a/app/static/public/css/video.css b/app/static/public/css/video.css index 7b93b57..1b7eb8d 100644 --- a/app/static/public/css/video.css +++ b/app/static/public/css/video.css @@ -675,15 +675,25 @@ body { margin-bottom: 12px; } -.slider-direction-mark { - margin-bottom: 6px; - font-size: 12px; - color: var(--accents-6); - line-height: 1.4; +.timeline-delete-zone { + width: 100%; + appearance: none; + background: transparent; + --timeline-track-bg: linear-gradient(90deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.95) 100%); } -#editTimeline { - width: 100%; +.timeline-delete-zone::-webkit-slider-runnable-track { + height: 8px; + border-radius: 999px; + background: var(--timeline-track-bg); + border: 1px solid rgba(148, 163, 184, 0.35); +} + +.timeline-delete-zone::-moz-range-track { + height: 8px; + border-radius: 999px; + background: var(--timeline-track-bg); + border: 1px solid rgba(148, 163, 184, 0.35); } .edit-meta-grid { diff --git a/app/static/public/js/video.js b/app/static/public/js/video.js index 729be95..75a14d9 100644 --- a/app/static/public/js/video.js +++ b/app/static/public/js/video.js @@ -194,6 +194,31 @@ return Math.max(0, Math.min(safe, maxMs)); } + function updateDeleteZoneTrack(inputEl) { + if (!inputEl) return; + const maxRaw = Number(inputEl.max || EDIT_TIMELINE_MAX); + const max = Number.isFinite(maxRaw) && maxRaw > 0 ? maxRaw : EDIT_TIMELINE_MAX; + const valueRaw = Number(inputEl.value || 0); + const value = Math.max(0, Math.min(max, Number.isFinite(valueRaw) ? valueRaw : 0)); + const pct = (value / max) * 100; + const side = String(inputEl.dataset.deleteSide || 'right'); + const warnPattern = 'repeating-linear-gradient(135deg, rgba(148,163,184,0.38) 0 7px, rgba(100,116,139,0.58) 7px 14px)'; + const keep = 'rgba(255,255,255,0.95)'; + let bg = ''; + if (side === 'left') { + bg = `linear-gradient(90deg, transparent 0%, transparent ${pct}%, ${keep} ${pct}%, ${keep} 100%), ${warnPattern}`; + } else { + bg = `linear-gradient(90deg, ${keep} 0%, ${keep} ${pct}%, transparent ${pct}%, transparent 100%), ${warnPattern}`; + } + inputEl.style.setProperty('--timeline-track-bg', bg); + } + + function refreshAllDeleteZoneTracks() { + updateDeleteZoneTrack(editTimeline); + updateDeleteZoneTrack(mergeTimelineA); + updateDeleteZoneTrack(mergeTimelineB); + } + function setSpliceButtonState(state) { if (!spliceBtn) return; const iconSplice = ''; @@ -1446,6 +1471,7 @@ const current = Number(editVideo.currentTime || 0); const ratio = Math.max(0, Math.min(1, current / duration)); editTimeline.value = String(Math.round(ratio * EDIT_TIMELINE_MAX)); + updateDeleteZoneTrack(editTimeline); lockedTimestampMs = clampEditTimestampMs(Math.round(current * 1000)); if (editTimeText) editTimeText.textContent = formatMs(lockedTimestampMs); } @@ -2494,6 +2520,7 @@ const ratio = Number(editTimeline.value || 0) / EDIT_TIMELINE_MAX; const nextTime = Math.max(0, Math.min(duration, duration * ratio)); editVideo.currentTime = nextTime; + updateDeleteZoneTrack(editTimeline); lockedTimestampMs = clampEditTimestampMs(Math.round(nextTime * 1000)); if (editTimeText) editTimeText.textContent = formatMs(lockedTimestampMs); lockFrameByCurrentTime(); @@ -2533,6 +2560,7 @@ mergeCutMsA = 0; if (mergeTimeTextA) mergeTimeTextA.textContent = formatMs(0); if (mergeTimelineA) mergeTimelineA.value = '0'; + updateDeleteZoneTrack(mergeTimelineA); }); } @@ -2545,6 +2573,7 @@ mergeCutMsB = 0; if (mergeTimeTextB) mergeTimeTextB.textContent = formatMs(0); if (mergeTimelineB) mergeTimelineB.value = '0'; + updateDeleteZoneTrack(mergeTimelineB); }); } @@ -2556,6 +2585,7 @@ const ratio = Number(mergeTimelineA.value || 0) / EDIT_TIMELINE_MAX; const nextTime = Math.max(0, Math.min(duration, duration * ratio)); mergeVideoPreviewA.currentTime = nextTime; + updateDeleteZoneTrack(mergeTimelineA); mergeCutMsA = Math.round(nextTime * 1000); if (mergeTimeTextA) mergeTimeTextA.textContent = formatMs(mergeCutMsA); }); @@ -2569,6 +2599,7 @@ const ratio = Number(mergeTimelineB.value || 0) / EDIT_TIMELINE_MAX; const nextTime = Math.max(0, Math.min(duration, duration * ratio)); mergeVideoPreviewB.currentTime = nextTime; + updateDeleteZoneTrack(mergeTimelineB); mergeCutMsB = Math.round(nextTime * 1000); if (mergeTimeTextB) mergeTimeTextB.textContent = formatMs(mergeCutMsB); }); @@ -2960,6 +2991,7 @@ updateMergeLabels(); updateHistoryCount(); updateManualActionsVisibility(); + refreshAllDeleteZoneTracks(); setSpliceButtonState('idle'); if (imageUrlInput && imageUrlInput.value.trim()) { const resolved = resolveReferenceByText(imageUrlInput.value.trim()); diff --git a/app/static/public/pages/video.html b/app/static/public/pages/video.html index 25fc6d1..73453d2 100644 --- a/app/static/public/pages/video.html +++ b/app/static/public/pages/video.html @@ -154,8 +154,7 @@
-
从这里开始拼接,右侧将由新视频接续
- +
00:00.000 总时长 - @@ -198,8 +197,7 @@
-
方向:保留左侧(起点 -> 当前帧)
- +
00:00.000 总时长 - @@ -212,8 +210,7 @@
-
方向:保留右侧(当前帧 -> 结尾)
- +
00:00.000 总时长 - @@ -321,7 +318,7 @@ - +