victor HF Staff commited on
Commit
2880ff3
·
verified ·
1 Parent(s): 109b45b

Show centered play button when video is paused

Browse files
Files changed (1) hide show
  1. 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();