|
194 | 194 | <p class="meta" id="resline">Résolution : <span id="resval">?</span></p> |
195 | 195 | {% endif %} |
196 | 196 |
|
197 | | - <div class="zoom-bar"> |
198 | | - <span>Zoom :</span> |
199 | | - <button class="zoom-btn active" data-zoom="1">x1</button> |
200 | | - <button class="zoom-btn" data-zoom="1.5">x1.5</button> |
201 | | - <button class="zoom-btn" data-zoom="2">x2</button> |
202 | | - </div> |
203 | | - |
204 | 197 | <section class="meta-ops"> |
205 | 198 | <div class="tagsline"> |
206 | 199 | {% for t in tags %}<a class="pill" href="/browse?tag={{ t|e }}">{{ t }}</a>{% endfor %} |
|
229 | 222 | <p><kbd>↑</kbd> / <kbd>↓</kbd> — Volume</p> |
230 | 223 | <p><kbd>F</kbd> — Plein écran</p> |
231 | 224 | <p><kbd>M</kbd> — Muet</p> |
232 | | - <p><kbd>Z</kbd> — Zoom (x1/x1.5/x2)</p> |
233 | 225 | </div> |
234 | 226 | </div> |
235 | 227 |
|
|
360 | 352 |
|
361 | 353 | <!-- Keyboard shortcuts handler --> |
362 | 354 | <script> |
363 | | - <script> |
364 | 355 | document.addEventListener('keydown', (e) => { |
365 | 356 | const v = document.getElementById('v'); |
366 | 357 | if (!v || e.target.matches('input, textarea, [contenteditable]')) return; |
367 | 358 |
|
368 | 359 | const key = e.key.toLowerCase(); |
369 | 360 | switch (key) { |
370 | 361 | case ' ': |
371 | | - case 'k': |
372 | | - e.preventDefault(); |
373 | | - v.paused ? v.play() : v.pause(); |
374 | | - break; |
375 | | - case 'j': |
376 | | - e.preventDefault(); |
377 | | - v.currentTime = Math.max(0, v.currentTime - 10); |
378 | | - break; |
379 | | - case 'l': |
380 | | - e.preventDefault(); |
381 | | - v.currentTime = Math.min(v.duration || 0, v.currentTime + 10); |
382 | | - break; |
383 | | - case 'f': |
384 | | - e.preventDefault(); |
385 | | - if (document.fullscreenElement) { |
386 | | - document.exitFullscreen?.(); |
| 362 | + case 'k': |
| 363 | + e.preventDefault(); |
| 364 | + v.paused ? v.play() : v.pause(); |
| 365 | + break; |
| 366 | + case 'j': |
| 367 | + e.preventDefault(); |
| 368 | + v.currentTime = Math.max(0, v.currentTime - 10); |
| 369 | + break; |
| 370 | + case 'l': |
| 371 | + e.preventDefault(); |
| 372 | + v.currentTime = Math.min(v.duration || 0, v.currentTime + 10); |
| 373 | + break; |
| 374 | + case 'f': |
| 375 | + e.preventDefault(); |
| 376 | + if (document.fullscreenElement) { |
| 377 | + document.exitFullscreen?.(); |
387 | 378 | } else { |
388 | | - (v.requestFullscreen || v.webkitRequestFullscreen || v.msRequestFullscreen)?.call(v); |
| 379 | + (v.requestFullscreen || v.webkitRequestFullscreen || v.msRequestFullscreen)?.call(v); |
389 | 380 | } |
390 | | - break; |
391 | | - case 'm': |
392 | | - e.preventDefault(); |
393 | | - v.muted = !v.muted; |
394 | | - break; |
395 | | - case 'z': |
396 | | - e.preventDefault(); |
397 | | - cycleZoom(); |
398 | | - break; |
399 | | - case 'arrowleft': |
400 | | - e.preventDefault(); |
401 | | - v.currentTime = Math.max(0, v.currentTime - 5); |
402 | | - break; |
403 | | - case 'arrowright': |
404 | | - e.preventDefault(); |
405 | | - v.currentTime = Math.min(v.duration || 0, v.currentTime + 5); |
406 | | - break; |
407 | | - case 'arrowup': |
408 | | - e.preventDefault(); |
409 | | - v.volume = Math.min(1, v.volume + 0.1); |
410 | | - break; |
411 | | - case 'arrowdown': |
412 | | - e.preventDefault(); |
413 | | - v.volume = Math.max(0, v.volume - 0.1); |
414 | | - break; |
| 381 | + break; |
| 382 | + case 'm': |
| 383 | + e.preventDefault(); |
| 384 | + v.muted = !v.muted; |
| 385 | + break; |
| 386 | + case 'arrowleft': |
| 387 | + e.preventDefault(); |
| 388 | + v.currentTime = Math.max(0, v.currentTime - 5); |
| 389 | + break; |
| 390 | + case 'arrowright': |
| 391 | + e.preventDefault(); |
| 392 | + v.currentTime = Math.min(v.duration || 0, v.currentTime + 5); |
| 393 | + break; |
| 394 | + case 'arrowup': |
| 395 | + e.preventDefault(); |
| 396 | + v.volume = Math.min(1, v.volume + 0.1); |
| 397 | + break; |
| 398 | + case 'arrowdown': |
| 399 | + e.preventDefault(); |
| 400 | + v.volume = Math.max(0, v.volume - 0.1); |
| 401 | + break; |
415 | 402 | } |
416 | 403 | }); |
417 | | - |
418 | | - // Zoom Logic |
419 | | - const zoomBtns = document.querySelectorAll('.zoom-btn'); |
420 | | - const playerWrap = document.querySelector('.player-wrap'); |
421 | | - const v = document.getElementById('v'); |
422 | | - let currentZoom = 1; |
423 | | - |
424 | | - function setZoom(zoom) { |
425 | | - if (!v || !playerWrap) return; |
426 | | - currentZoom = parseFloat(zoom); |
427 | | - |
428 | | - // Update UI buttons |
429 | | - zoomBtns.forEach(b => { |
430 | | - b.classList.toggle('active', parseFloat(b.dataset.zoom) === currentZoom); |
431 | | - }); |
432 | | - |
433 | | - if (currentZoom === 1) { |
434 | | - playerWrap.style.width = '100%'; |
435 | | - playerWrap.style.maxWidth = '1400px'; |
436 | | - v.style.maxHeight = '80vh'; // Restore height constraint |
437 | | - } else { |
438 | | - // Zoom logic: Scale relative to viewport width |
439 | | - // We remove constraints to allow "true" zoom (upscaling) |
440 | | - const viewportW = window.innerWidth; |
441 | | - let targetW = viewportW * currentZoom; |
442 | | - |
443 | | - playerWrap.style.maxWidth = 'none'; |
444 | | - playerWrap.style.width = targetW + 'px'; |
445 | | - v.style.maxHeight = 'none'; // Uncap height to allow proportional growth |
446 | | - } |
447 | | - } |
448 | | - |
449 | | - // Initialize zoom on load to setup native constraints if needed |
450 | | - if(v) { |
451 | | - v.addEventListener('loadedmetadata', () => { |
452 | | - // Optional: Disable x1.5/x2 if video is too small? |
453 | | - // For now keep it simple. |
454 | | - }); |
455 | | - } |
456 | | - |
457 | | - zoomBtns.forEach(btn => { |
458 | | - btn.addEventListener('click', () => setZoom(btn.dataset.zoom)); |
459 | | - }); |
460 | | - |
461 | | - function cycleZoom() { |
462 | | - const zooms = [1, 1.5, 2]; |
463 | | - const idx = zooms.indexOf(currentZoom); |
464 | | - const next = (idx + 1) % zooms.length; |
465 | | - setZoom(zooms[next]); |
466 | | - } |
467 | 404 | </script> |
468 | 405 |
|
469 | 406 | <button id="backTop" class="backtop" aria-label="Haut de page" title="Haut de page" |
470 | 407 | onclick="return (function(){try{var a=document.getElementById('___topanchor');if(!a){a=document.createElement('div');a.id='___topanchor';document.body.insertBefore(a,document.body.firstChild);}var targets=[document.scrollingElement,document.documentElement,document.body];var extra=document.querySelectorAll('main,.content,.container,.page,.grid,#app,#root,#content,.scroll,.scrollable');extra.forEach(function(n){targets.push(n)});var done=false;for(var i=0;i<targets.length;i++){var t=targets[i];if(!t)continue;if(t.scrollTo){t.scrollTo({top:0,behavior:'smooth'});done=true;}else if(typeof t.scrollTop!==\'undefined\'){t.scrollTop=0;done=true;}}if(!done){location.hash='#___topanchor';}}catch(e){location.hash='#___topanchor';}return false;})()">↑</button> |
471 | 408 |
|
472 | 409 | <script> |
473 | | - (function () { |
| 410 | + (function () { |
474 | 411 | var btn = document.getElementById('backTop'); |
475 | 412 | if (!btn) return; |
476 | | - function toggle() {(window.scrollY > 200 ? btn.classList.add : btn.classList.remove)('show'); } |
477 | | - window.addEventListener('scroll', toggle, {passive: true }); |
| 413 | + function toggle() { (window.scrollY > 200 ? btn.classList.add : btn.classList.remove)('show'); } |
| 414 | + window.addEventListener('scroll', toggle, { passive: true }); |
478 | 415 | toggle(); |
479 | | - btn.addEventListener('click', function () {window.scrollTo({ top: 0, behavior: 'smooth' }); }); |
| 416 | + btn.addEventListener('click', function () { window.scrollTo({ top: 0, behavior: 'smooth' }); }); |
480 | 417 | })(); |
481 | 418 | </script> |
482 | 419 |
|
483 | 420 | <script> |
484 | | - (function () { |
| 421 | + (function () { |
485 | 422 | const v = document.getElementById('v'); |
486 | 423 | const b = document.getElementById('btnFS'); |
487 | 424 | function enterFS(el) { |
488 | 425 | const c = el.closest('.player') || el; |
489 | | - const target = c; |
490 | | - if (document.fullscreenElement) { |
491 | | - document.exitFullscreen().catch(() => { }); |
492 | | - return; |
| 426 | + const target = c; |
| 427 | + if (document.fullscreenElement) { |
| 428 | + document.exitFullscreen().catch(() => { }); |
| 429 | + return; |
493 | 430 | } |
494 | | - (target.requestFullscreen || target.webkitRequestFullscreen || target.msRequestFullscreen || target.mozRequestFullScreen)?.call(target); |
| 431 | + (target.requestFullscreen || target.webkitRequestFullscreen || target.msRequestFullscreen || target.mozRequestFullScreen)?.call(target); |
495 | 432 | } |
496 | 433 | if (b && v) { |
497 | 434 | b.addEventListener('click', function (e) { e.preventDefault(); enterFS(v); }); |
|
500 | 437 | </script> |
501 | 438 |
|
502 | 439 | <script>/*BACKTOP_FIX_LISTENER*/ |
503 | | - (function () { |
| 440 | + (function () { |
504 | 441 | try { |
505 | 442 | var btn = document.getElementById('backTop'); |
506 | | - if (!btn) return; |
507 | | - function __goTop__(e) { |
| 443 | + if (!btn) return; |
| 444 | + function __goTop__(e) { |
508 | 445 | try { |
509 | 446 | var el = document.scrollingElement || document.documentElement || document.body; |
510 | | - if (el && el.scrollTo) {el.scrollTo({ top: 0, behavior: 'smooth' }); } |
511 | | - else {window.scrollTo(0, 0); } |
512 | | - } catch (_) {window.scrollTo(0, 0); } |
513 | | - if (e) {e.preventDefault && e.preventDefault(); e.stopPropagation && e.stopPropagation(); } |
514 | | - return false; |
| 447 | + if (el && el.scrollTo) { el.scrollTo({ top: 0, behavior: 'smooth' }); } |
| 448 | + else { window.scrollTo(0, 0); } |
| 449 | + } catch (_) { window.scrollTo(0, 0); } |
| 450 | + if (e) { e.preventDefault && e.preventDefault(); e.stopPropagation && e.stopPropagation(); } |
| 451 | + return false; |
515 | 452 | } |
516 | | - btn.addEventListener('click', __goTop__, true); |
517 | | - btn.onclick = __goTop__; |
| 453 | + btn.addEventListener('click', __goTop__, true); |
| 454 | + btn.onclick = __goTop__; |
518 | 455 | } catch (_) { } |
519 | 456 | })(); |
520 | 457 | </script> |
521 | 458 |
|
522 | 459 | <script> |
523 | | - // __VID_PROGRESS__ |
524 | | - (function () { |
| 460 | + // __VID_PROGRESS__ |
| 461 | + (function () { |
525 | 462 | try { |
526 | 463 | var v = document.querySelector('video'); |
527 | | - if (!v) return; |
528 | | - var vid = (document.body.getAttribute('data-vid') || location.pathname.split('/').pop() || '').trim(); |
529 | | - function key() { return 'progress::' + vid; } |
530 | | - v.addEventListener('loadedmetadata', function () { |
| 464 | + if (!v) return; |
| 465 | + var vid = (document.body.getAttribute('data-vid') || location.pathname.split('/').pop() || '').trim(); |
| 466 | + function key() { return 'progress::' + vid; } |
| 467 | + v.addEventListener('loadedmetadata', function () { |
531 | 468 | try { |
532 | 469 | var s = localStorage.getItem(key()); |
533 | | - if (s) { |
| 470 | + if (s) { |
534 | 471 | var t = parseFloat(s) || 0; |
535 | | - if (t > 1 && t < (v.duration || 1) - 1) {v.currentTime = t; } |
| 472 | + if (t > 1 && t < (v.duration || 1) - 1) { v.currentTime = t; } |
536 | 473 | } |
537 | 474 | } catch (e) { } |
538 | | - }, {once: true }); |
539 | | - var saveTick = 0; |
540 | | - v.addEventListener('timeupdate', function () { |
| 475 | + }, { once: true }); |
| 476 | + var saveTick = 0; |
| 477 | + v.addEventListener('timeupdate', function () { |
541 | 478 | if (++saveTick % 3) return; |
542 | | - try {localStorage.setItem(key(), String(v.currentTime || 0)); } catch (e) { } |
| 479 | + try { localStorage.setItem(key(), String(v.currentTime || 0)); } catch (e) { } |
543 | 480 | }); |
544 | | - v.addEventListener('ended', function () { try {localStorage.removeItem(key()); } catch (e) { } }); |
545 | | - // Gestes mobiles |
546 | | - var lastTap = 0; |
547 | | - v.addEventListener('touchend', function (ev) { |
| 481 | + v.addEventListener('ended', function () { try { localStorage.removeItem(key()); } catch (e) { } }); |
| 482 | + // Gestes mobiles |
| 483 | + var lastTap = 0; |
| 484 | + v.addEventListener('touchend', function (ev) { |
548 | 485 | var now = Date.now(); |
549 | | - var rect = v.getBoundingClientRect(); |
550 | | - var x = (ev.changedTouches && ev.changedTouches[0] ? ev.changedTouches[0].clientX : 0) - rect.left; |
551 | | - if (now - lastTap < 350) { |
552 | | - if (x < rect.width / 2) {v.currentTime = Math.max(0, (v.currentTime || 0) - 10); } |
553 | | - else {v.currentTime = Math.min(v.duration || v.currentTime + 10, (v.currentTime || 0) + 10); } |
554 | | - lastTap = 0; ev.preventDefault(); return false; |
555 | | - } else {lastTap = now; } |
556 | | - }, {passive: false }); |
557 | | - var startX = null; |
558 | | - v.addEventListener('touchstart', function (ev) {startX = (ev.touches && ev.touches[0] ? ev.touches[0].clientX : null); }, {passive: true }); |
559 | | - v.addEventListener('touchend', function (ev) { |
| 486 | + var rect = v.getBoundingClientRect(); |
| 487 | + var x = (ev.changedTouches && ev.changedTouches[0] ? ev.changedTouches[0].clientX : 0) - rect.left; |
| 488 | + if (now - lastTap < 350) { |
| 489 | + if (x < rect.width / 2) { v.currentTime = Math.max(0, (v.currentTime || 0) - 10); } |
| 490 | + else { v.currentTime = Math.min(v.duration || v.currentTime + 10, (v.currentTime || 0) + 10); } |
| 491 | + lastTap = 0; ev.preventDefault(); return false; |
| 492 | + } else { lastTap = now; } |
| 493 | + }, { passive: false }); |
| 494 | + var startX = null; |
| 495 | + v.addEventListener('touchstart', function (ev) { startX = (ev.touches && ev.touches[0] ? ev.touches[0].clientX : null); }, { passive: true }); |
| 496 | + v.addEventListener('touchend', function (ev) { |
560 | 497 | if (startX == null) return; |
561 | | - var x = (ev.changedTouches && ev.changedTouches[0] ? ev.changedTouches[0].clientX : startX); |
562 | | - var dx = x - startX; |
| 498 | + var x = (ev.changedTouches && ev.changedTouches[0] ? ev.changedTouches[0].clientX : startX); |
| 499 | + var dx = x - startX; |
563 | 500 | if (Math.abs(dx) > 60) { |
564 | | - if (dx > 0) {v.currentTime = Math.max(0, (v.currentTime || 0) - 15); } |
565 | | - else {v.currentTime = Math.min(v.duration || v.currentTime + 15, (v.currentTime || 0) + 15); } |
566 | | - ev.preventDefault(); return false; |
| 501 | + if (dx > 0) { v.currentTime = Math.max(0, (v.currentTime || 0) - 15); } |
| 502 | + else { v.currentTime = Math.min(v.duration || v.currentTime + 15, (v.currentTime || 0) + 15); } |
| 503 | + ev.preventDefault(); return false; |
567 | 504 | } |
568 | | - }, {passive: false }); |
| 505 | + }, { passive: false }); |
569 | 506 | } catch (e) { } |
570 | 507 | })(); |
571 | 508 | </script> |
|
0 commit comments