From 627a016515970e82f83e027831febbd0efe4531a Mon Sep 17 00:00:00 2001 From: j Date: Sat, 14 Dec 2024 19:16:41 +0000 Subject: [PATCH] better mobile seek bar --- static/mobile/css/style.css | 72 ++++++++++++++++++++++++++++++ static/mobile/js/VideoPlayer.js | 78 +++++++++++++++++++-------------- 2 files changed, 118 insertions(+), 32 deletions(-) diff --git a/static/mobile/css/style.css b/static/mobile/css/style.css index 2dd8e28c..1ca261f5 100644 --- a/static/mobile/css/style.css +++ b/static/mobile/css/style.css @@ -201,3 +201,75 @@ ol li { width: 64px; height: 64px; } + + +.seekbar { + padding: 12px 22px; + position: relative; + width: 100%; +} +.fullscreen .seekbar { + padding: 28px 22px; +} + +.seekbar-progress { + height: 10px; + border: solid 1px #B1B1B1; +} + +.seekbar-progress [role="progressbar"] { + height: 100%; + position: relative; + background-color: #B1B1B180; +} + +.seekbar-progress [role="progressbar"]:after { + content: " "; + display: block; + width: 14px; + height: 14px; + position: absolute; + top: -3px; + right: -7px; + border: 2px solid #B1B1B180; + background-color: #B1B1B180; +} + +.seekbar input[type="range"] { + -webkit-appearance: none; + width: 100%; + height: 100%; + margin: 0; + position: absolute; + top: 0; + left: 0; + z-index: 2; + background: transparent; + outline: 0; + border: 0; +} + +.seekbar input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + display: block; + width: 48px; + height: 48px; + background-color: transparent; +} + +.seekbar input[type="range"]::-moz-range-thumb { + display: block; + width: 48px; + height: 48px; + background: transparent; + border: 0; +} + +.seekbar input[type="range"]::-moz-range-track { + background: transparent; + border: 0; +} + +.seekbar input[type="range"]::-moz-focus-outer { + border: 0; +} diff --git a/static/mobile/js/VideoPlayer.js b/static/mobile/js/VideoPlayer.js index af219c54..f1503387 100644 --- a/static/mobile/js/VideoPlayer.js +++ b/static/mobile/js/VideoPlayer.js @@ -153,9 +153,11 @@ window.VideoPlayer = function(options) { ${icon.mute}
-
-
- +
+ +
+
+
@@ -223,15 +225,28 @@ window.VideoPlayer = function(options) { } } var showControls + function hideControlsLater() { + showControls = setTimeout(() => { + if (touching) { + hideControlsLater() + } else { + self.controls.style.opacity = that.paused ? '1' : '0' + showControls = null + } + }, 3000) + } var toggleControls = event => { + if (event.target.tagName == "INPUT") { + if (showControls) { + clearTimeout(showControls) + } + return + } if (self.controls.style.opacity == '0') { event.preventDefault() event.stopPropagation() self.controls.style.opacity = '1' - showControls = setTimeout(() => { - self.controls.style.opacity = that.paused ? '1' : '0' - showControls = null - }, 3000) + hideControlsLater() } else { self.controls.style.opacity = '0' } @@ -241,10 +256,7 @@ window.VideoPlayer = function(options) { clearTimeout(showControls) } self.controls.style.opacity = '1' - showControls = setTimeout(() => { - self.controls.style.opacity = that.paused ? '1' : '0' - showControls = null - }, 3000) + hideControlsLater() }) self.controls.addEventListener("mouseleave", event => { if (showControls) { @@ -253,7 +265,13 @@ window.VideoPlayer = function(options) { self.controls.style.opacity = that.paused ? '1' : '0' showControls = null }) + self.controls.addEventListener("touchstart", event => { + touching = true + }) self.controls.addEventListener("touchstart", toggleControls) + self.controls.addEventListener("touchend", event => { + touching = false + }) self.controls.querySelector('.toggle').addEventListener("click", toggleVideo) self.controls.querySelector('.volume').addEventListener("click", toggleSound) self.controls.querySelector('.fullscreen-btn').addEventListener("click", toggleFullscreen) @@ -310,6 +328,7 @@ window.VideoPlayer = function(options) { that.append(unblock) }) var loading = true + var touching = false that.brightness(0) that.addEventListener("loadedmetadata", event => { // @@ -331,34 +350,29 @@ window.VideoPlayer = function(options) { } }) - var time = that.querySelector('.controls .time div'), - progress = that.querySelector('.controls .position .progress') - that.querySelector('.controls .position').addEventListener("click", event => { - var bar = event.target - while (bar && !bar.classList.contains('bar')) { - bar = bar.parentElement - } - if (bar && bar.classList.contains('bar')) { - event.preventDefault() - event.stopPropagation() - var rect = bar.getBoundingClientRect() - var x = event.clientX - rect.x - var percent = x / rect.width - var position = percent * self.options.duration - if (self.options.position) { - position += self.options.position - } - progress.style.width = (100 * percent) + '%' - that.currentTime(position) - } + var time = that.querySelector('.controls .time div'); + const progressbar = that.querySelector('.seekbar div[role="progressbar"]'); + function setProgressPosition(value) { + progressbar.style.width = value + '%'; + progressbar.setAttribute('aria-valuenow', value); + + } + that.querySelector('.controls .position input').addEventListener('input', function(event){ + event.preventDefault() + event.stopPropagation() + setProgressPosition(this.value) + var position = this.value/100 * self.options.duration + that.currentTime(position) + hideControlsLater() }) + that.addEventListener("timeupdate", event => { var currentTime = that.currentTime(), duration = self.options.duration if (self.options.position) { currentTime -= self.options.position } - progress.style.width = (100 * currentTime / duration) + '%' + setProgressPosition(100 * currentTime / duration) duration = formatDuration(duration) currentTime = formatDuration(currentTime) while (duration && duration.startsWith('00:')) {