Spaces:
Sleeping
Sleeping
Show centered play button when video is paused
Browse files- index.html +38 -1
index.html
CHANGED
|
@@ -149,6 +149,19 @@
|
|
| 149 |
}
|
| 150 |
.video-wrap { position: relative; background: #050506; }
|
| 151 |
video { width: 100%; aspect-ratio: 16 / 9; display: block; background: #050506; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
.caption-overlay {
|
| 153 |
position: absolute; left: 12px; right: 12px; bottom: 12px;
|
| 154 |
padding: 10px 12px; border: 1px solid rgba(255,255,255,.08); border-radius: var(--radius);
|
|
@@ -294,8 +307,11 @@
|
|
| 294 |
|
| 295 |
<div class="viewer">
|
| 296 |
<section class="stage">
|
| 297 |
-
<div class="video-wrap">
|
| 298 |
<video id="video" controls playsinline></video>
|
|
|
|
|
|
|
|
|
|
| 299 |
<div class="caption-overlay" id="captionOverlay">
|
| 300 |
<small>Active caption</small>
|
| 301 |
<div id="activeCaption" class="empty">Run analysis to sync captions with playback.</div>
|
|
@@ -351,7 +367,9 @@
|
|
| 351 |
dropEmpty: $("dropEmpty"),
|
| 352 |
fileName: $("fileName"),
|
| 353 |
videoInput: $("videoInput"),
|
|
|
|
| 354 |
video: $("video"),
|
|
|
|
| 355 |
taskGroup: $("taskGroup"),
|
| 356 |
eventField: $("eventField"),
|
| 357 |
eventInput: $("eventInput"),
|
|
@@ -419,6 +437,20 @@
|
|
| 419 |
els.dropzone.classList.add("has-file");
|
| 420 |
els.fileName.textContent = label || file?.name || "video";
|
| 421 |
setStatus("Clip loaded", "file-video");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 422 |
}
|
| 423 |
function playCurrentVideo() {
|
| 424 |
els.video.muted = true;
|
|
@@ -651,9 +683,14 @@
|
|
| 651 |
});
|
| 652 |
els.eventInput.addEventListener("input", () => { state.exampleMatchesPreset = false; });
|
| 653 |
els.video.addEventListener("timeupdate", updateActiveCaption);
|
|
|
|
|
|
|
|
|
|
| 654 |
els.video.addEventListener("loadedmetadata", () => {
|
| 655 |
els.durationTime.textContent = seconds(els.video.duration || 0);
|
|
|
|
| 656 |
});
|
|
|
|
| 657 |
els.runBtn.addEventListener("click", analyze);
|
| 658 |
|
| 659 |
resetAnalysis();
|
|
|
|
| 149 |
}
|
| 150 |
.video-wrap { position: relative; background: #050506; }
|
| 151 |
video { width: 100%; aspect-ratio: 16 / 9; display: block; background: #050506; }
|
| 152 |
+
.video-play-toggle {
|
| 153 |
+
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
|
| 154 |
+
width: 48px; height: 48px; display: grid; place-items: center;
|
| 155 |
+
border-radius: 999px; color: var(--accent-ink); background: rgba(244,244,245,.92);
|
| 156 |
+
box-shadow: 0 10px 30px rgba(0,0,0,.28); z-index: 4;
|
| 157 |
+
transition: opacity .15s ease, transform .15s ease, background .15s ease;
|
| 158 |
+
}
|
| 159 |
+
.video-play-toggle svg { width: 20px; height: 20px; margin-left: 2px; }
|
| 160 |
+
.video-play-toggle:hover { background: #fff; transform: translate(-50%, -50%) scale(1.04); }
|
| 161 |
+
.video-wrap.no-video .video-play-toggle,
|
| 162 |
+
.video-wrap.playing .video-play-toggle {
|
| 163 |
+
opacity: 0; pointer-events: none; transform: translate(-50%, -50%) scale(.96);
|
| 164 |
+
}
|
| 165 |
.caption-overlay {
|
| 166 |
position: absolute; left: 12px; right: 12px; bottom: 12px;
|
| 167 |
padding: 10px 12px; border: 1px solid rgba(255,255,255,.08); border-radius: var(--radius);
|
|
|
|
| 307 |
|
| 308 |
<div class="viewer">
|
| 309 |
<section class="stage">
|
| 310 |
+
<div class="video-wrap no-video" id="videoWrap">
|
| 311 |
<video id="video" controls playsinline></video>
|
| 312 |
+
<button class="video-play-toggle" id="videoPlayToggle" type="button" aria-label="Play video">
|
| 313 |
+
<i data-lucide="play"></i>
|
| 314 |
+
</button>
|
| 315 |
<div class="caption-overlay" id="captionOverlay">
|
| 316 |
<small>Active caption</small>
|
| 317 |
<div id="activeCaption" class="empty">Run analysis to sync captions with playback.</div>
|
|
|
|
| 367 |
dropEmpty: $("dropEmpty"),
|
| 368 |
fileName: $("fileName"),
|
| 369 |
videoInput: $("videoInput"),
|
| 370 |
+
videoWrap: $("videoWrap"),
|
| 371 |
video: $("video"),
|
| 372 |
+
videoPlayToggle: $("videoPlayToggle"),
|
| 373 |
taskGroup: $("taskGroup"),
|
| 374 |
eventField: $("eventField"),
|
| 375 |
eventInput: $("eventInput"),
|
|
|
|
| 437 |
els.dropzone.classList.add("has-file");
|
| 438 |
els.fileName.textContent = label || file?.name || "video";
|
| 439 |
setStatus("Clip loaded", "file-video");
|
| 440 |
+
syncPlayOverlay();
|
| 441 |
+
}
|
| 442 |
+
function syncPlayOverlay() {
|
| 443 |
+
const hasVideo = Boolean(els.video.getAttribute("src"));
|
| 444 |
+
const playing = hasVideo && !els.video.paused && !els.video.ended;
|
| 445 |
+
els.videoWrap.classList.toggle("no-video", !hasVideo);
|
| 446 |
+
els.videoWrap.classList.toggle("playing", playing);
|
| 447 |
+
}
|
| 448 |
+
function toggleVideoPlayback() {
|
| 449 |
+
if (!els.video.getAttribute("src")) return;
|
| 450 |
+
if (els.video.ended) els.video.currentTime = 0;
|
| 451 |
+
if (els.video.paused) els.video.play().catch(() => {});
|
| 452 |
+
else els.video.pause();
|
| 453 |
+
syncPlayOverlay();
|
| 454 |
}
|
| 455 |
function playCurrentVideo() {
|
| 456 |
els.video.muted = true;
|
|
|
|
| 683 |
});
|
| 684 |
els.eventInput.addEventListener("input", () => { state.exampleMatchesPreset = false; });
|
| 685 |
els.video.addEventListener("timeupdate", updateActiveCaption);
|
| 686 |
+
["play", "pause", "ended", "loadeddata", "emptied"].forEach((name) => {
|
| 687 |
+
els.video.addEventListener(name, syncPlayOverlay);
|
| 688 |
+
});
|
| 689 |
els.video.addEventListener("loadedmetadata", () => {
|
| 690 |
els.durationTime.textContent = seconds(els.video.duration || 0);
|
| 691 |
+
syncPlayOverlay();
|
| 692 |
});
|
| 693 |
+
els.videoPlayToggle.addEventListener("click", toggleVideoPlayback);
|
| 694 |
els.runBtn.addEventListener("click", analyze);
|
| 695 |
|
| 696 |
resetAnalysis();
|