Плавное перемещение ползунка у видео
Если продолжительность видео скажем секунд 5-10, то ползунок перемещается шагами, нету в нем плавности.
Пробовал
transition: 30ms height ease-in-out;
То получается, что ползунок под конец не успевает. Как я понял через css не выход, поскольку продолжительность не большая и в ширину ползунок может быть как больше так и меньше.
Быть может у кого есть готовое решение, так чтобы учитывать продолжительность видео и ширину ползунка. Подстраивать анимацию под данные параметры через js?
Пример
let interval = 10, // 10 процентов, может 20 а может и 50.
last = 0;
setInterval(_ => {
pr.style.width = (last = (interval + last)) + '%';
}, 1000);
#pr {
height: 5px;
background: red;
position: fixed;
bottom:0;
left:0;
width: 0;
}
<div id='pr'></div>
Собственно пример, может быть шаг в 5% от ширины блока, может быть 50%. Все зависит от продолжительности видео. Ширина блока в процентах.
На сколько я понимаю, через css реализовать плавную анимацию невозможно. Иначе ползунок будет не успевать или наоборот, так как продолжительность видео разная..
Ответы (3 шт):
Можете попробовать так:
const videoLengthinSec = 10;
const speed = 1000;
let currentSec = 0;
let timeout = null;
const setProgress = () => {
let currentLength = (currentSec++ / videoLengthinSec) * 100;
if (currentLength > 100) {
currentLength = 100;
clearTimeout(timeout);
}
pr.style.width = `${currentLength}%`;
timeout = setTimeout(setProgress, speed);
}
timeout = setTimeout(setProgress, speed);
#pr {
height: 5px;
background: red;
position: fixed;
bottom: 0;
left: 0;
width: 0;
transition: 1s width linear;
}
<div id='pr'></div>
Решение основано на частоте удлинения прогресс бара, и она обратно пропорциональна длине видео (чем длиннее видео тем реже длина увеличивается)
В формуле 1000/ (100/n):
n- это количество секунд- 100 - это
100%(для обратной пропорциональности) 1000- одна секунда и соответственно время видео должно быть в секундах (поэтому если видео 3 минуты нужно передать 180 в качестве n)
function timer(n, id){
let max = n
setInterval(_ => {
id.innerText = `${max - n--} sec`
if (n === 0){
n = max
}
}, 1000);
}
function inc(n, id){
let last = 0;
setInterval(_ => {
id.style.width = (last += 1) + '%';
if (last === 100){
id.style.width = '0px'
last = 0
}
}, 1000/ (100/n));
}
inc(10, pr)
timer(10,pr)
inc(20, pr2)
timer(20,pr2)
inc(50, pr3)
timer(50,pr3)
#pr {
height: 5px;
background: red;
position: fixed;
bottom:160px;
left:0;
width: 0;
}
#pr2 {
height: 5px;
background: orange;
position: fixed;
bottom:130px;
left:0;
width: 0;
}
#pr3 {
height: 5px;
background: green;
position: fixed;
bottom:100px;
left:0;
width: 0;
}
<div id='pr'>0 sec</div>
<div id='pr2'>0 sec</div>
<div id='pr3'>0 sec</div>
Для правильного рассчёта и плавного перемещения ползунка у видео необходимо использовать такие свойства элемента видео:
video.currentTime - текущая временная позиция во время воспроизведения;
video.duration - подолжительность видеофайла.
setInterval() с частотой повторения одна секунда не подходит для плавного движения ползунка при воспроизведении коротких видеофайлов.
Есть три способа плавного воспроизведения:
1 - использование свойства video.ontimeupdate:
video.ontimeupdate = () => {
polzunok.style.width = video.currentTime / video.duration *
progressWidth + "px";
}
Это срабатывает 4 раза в секунду, что даёт не очень высокую плавность.
2 - использование setInterval() с периодом в пределах 20 - 100 милисекунд:
setInterval(_ => {
polzunok.style.width =
video.currentTime / video.duration * progressWidth + "px";
}, 20);
3 - использование requestAnimationFrame():
const step = () => {
polzunok.style.width = video.currentTime / video.duration *
progressWidth + "px";
requestAnimationFrame(step);
}
requestAnimationFrame(step);
Плавными являются второй и третий варианты.
Следующий код является дополняющим до полного кода примера, в который нужно будет вставить предварительно выбранный вами вариант обеспечения плавности проигрывания:
video.ontimeupdate = () => {
polzunok.style.width = video.currentTime / video.duration * progressWidth + "px";
}
setInterval(_ => {
polzunok.style.width = video.currentTime / video.duration * progressWidth + "px";
}, 20);
const step = () => {
polzunok.style.width = video.currentTime / video.duration * progressWidth + "px";
requestAnimationFrame(step);
}
requestAnimationFrame(step);
<style>
#contauner{
border-style: solid;
}
#polzunok{
width: 0px;
height: 15px;
background: red;
}
</style>
<video id=video src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4" controls width="300"></video><br /><br />
<div id=contauner><div id=polzunok></div></div>
<script>
let progressWidth = 300; // ширина прогрессбара
contauner.style.width = progressWidth + "px";
// сюда вставляем код выбранного способа
</script>