patx/demo
optimize mobile scroll no video controls
Commit 5888b61 · patx · 2026-08-16T02:38:58-04:00
Comments
No comments yet.
Diff
diff --git a/docs/voldservices/index.html b/docs/voldservices/index.html
index 2be7ff9..f8371f8 100644
--- a/docs/voldservices/index.html
+++ b/docs/voldservices/index.html
@@ -423,9 +423,19 @@
.hero-media video {
z-index: 1;
opacity: 0;
+ pointer-events: none;
transition: opacity .18s ease-out;
}
.hero-media.is-video-ready video { opacity: 1; }
+ .hero-media video::-webkit-media-controls,
+ .hero-media video::-webkit-media-controls-panel,
+ .hero-media video::-webkit-media-controls-play-button,
+ .hero-media video::-webkit-media-controls-start-playback-button {
+ display: none !important;
+ -webkit-appearance: none;
+ opacity: 0;
+ pointer-events: none;
+ }
.hero-media::after {
content: "";
position: absolute;
@@ -1270,7 +1280,9 @@
<video
id="hero-video"
poster="https://gitman.io/patx/demo/raw/docs/voldservices/img/hero-scrub-poster.jpg"
- muted playsinline webkit-playsinline autoplay preload="auto"
+ muted playsinline webkit-playsinline preload="auto"
+ controlslist="nodownload nofullscreen noremoteplayback"
+ disablepictureinpicture disableremoteplayback
aria-hidden="true" tabindex="-1">
<source media="(max-width: 720px)" src="https://gitman.io/patx/demo/raw/docs/voldservices/hero-scrub-mobile.mp4" type="video/mp4" />
<source src="https://gitman.io/patx/demo/raw/docs/voldservices/hero-scrub.mp4" type="video/mp4" />
@@ -1929,6 +1941,8 @@
var heroVideoReady = false;
var heroVideoPrimed = false;
var heroVideoPrimePending = false;
+ var heroTouchStarted = false;
+ var heroUsesTouch = ('ontouchstart' in window) || navigator.maxTouchPoints > 0;
var heroVideoVisible = false;
var heroVideoRevealPending = false;
var heroVideoProgress = 0;
@@ -1989,29 +2003,23 @@
function finishHeroVideoPrime() {
heroVideo.pause();
- heroVideo.autoplay = false;
- heroVideo.removeAttribute('autoplay');
heroVideoPrimePending = false;
heroVideoPrimed = true;
heroVideoReady = true;
- window.removeEventListener('touchstart', primeHeroVideo);
+ window.removeEventListener('touchstart', primeHeroVideoFromTouch);
syncHeroVideo(heroVideoProgress, true);
}
function usePausedSeekFallback() {
heroVideo.pause();
- heroVideo.autoplay = false;
- heroVideo.removeAttribute('autoplay');
heroVideoPrimePending = false;
heroVideoReady = true;
syncHeroVideo(heroVideoProgress, true);
}
// iOS may load metadata for a muted video without activating its decoder.
- // A brief hidden play/pause primes frame presentation so later paused
- // currentTime changes repaint while the user scrolls. Muted inline play
- // is allowed automatically; the first touch provides a second chance
- // when Low Power Mode or a browser policy blocks autoplay.
+ // On touch devices, a brief hidden play/pause on the first scroll touch
+ // primes frame presentation without autoplay or visible player chrome.
function primeHeroVideo() {
if (reduceMotion || heroVideoPrimed || heroVideoPrimePending || heroVideo.readyState < 1) return;
@@ -2027,16 +2035,25 @@
}
}
+ function primeHeroVideoFromTouch() {
+ heroTouchStarted = true;
+ primeHeroVideo();
+ }
+
+ function prepareHeroVideo() {
+ if (!heroUsesTouch || heroTouchStarted) primeHeroVideo();
+ }
+
if (reduceMotion) {
- heroVideo.autoplay = false;
- heroVideo.removeAttribute('autoplay');
heroVideo.pause();
} else {
- heroVideo.addEventListener('loadedmetadata', primeHeroVideo);
- window.addEventListener('touchstart', primeHeroVideo, { passive: true });
+ heroVideo.addEventListener('loadedmetadata', prepareHeroVideo);
+ if (heroUsesTouch) {
+ window.addEventListener('touchstart', primeHeroVideoFromTouch, { passive: true });
+ }
// Cached media can reach metadata before this bottom-of-page script runs.
- if (heroVideo.readyState >= 1) primeHeroVideo();
+ if (heroVideo.readyState >= 1) prepareHeroVideo();
}
// If the user scrolls again while a seek is being decoded, catch the