Added support for dragging the progress bar to seek in the video

This commit is contained in:
Erik Thuning 2025-02-06 14:28:14 +01:00
parent 8323ea61dd
commit 77151ceef8

@ -961,6 +961,9 @@ input[type="range"]::-ms-track {
// the container element for the progress bar
this._progressContainer = null;
// variable to keep track of dragging state on progressbar
this._dragging = false;
// the element displaying buffer state
this._progressBuffer = null;
@ -1546,25 +1549,40 @@ input[type="range"]::-ms-track {
popup.style.left = pos + 'px';
});
// Enable seeking
// Enable seeking by click
this._progressContainer.addEventListener('click', (event) => {
const bounds =
this._progressContainer.getBoundingClientRect();
const xRel = event.clientX - bounds.x;
const fraction = xRel / this._progressContainer.clientWidth;
const time = fraction * this._controlSource.duration;
const time = this.setProgressByPosition(event.clientX);
this.setTime(time);
});
// Enable seeking by drag
this._progressContainer.addEventListener('mousedown', (event) => {
this._dragging = true;
});
// These listeners are on the root so the user doesn't have to
// be super precise with the mouse while dragging.
this._root.addEventListener('mouseup', (event) => {
if(this._dragging) {
this._dragging = false;
const time = this.setProgressByPosition(event.clientX);
this.setTime(time);
}
});
this._root.addEventListener('mousemove', (event) => {
if(!this._dragging) {
return;
}
this.setProgressByPosition(event.clientX);
});
// Initialize progressbar
this._controlSource.addEventListener('timeupdate', (event) => {
if(this._dragging) {
return;
}
const elapsed = this._controlSource.currentTime;
this._elapsed.textContent = this.formatTime(elapsed);
const progressWidth = (
elapsed
/ this._controlSource.duration
* this._progressContainer.clientWidth);
this._progressBar.style.width = progressWidth + 'px';
this.setProgressByTime(elapsed);
});
}
@ -1952,6 +1970,47 @@ input[type="range"]::-ms-track {
});
}
/*
* Set the width of the progress bar.
*
* The arg 'fraction' gives the desired width of the bar as a
* fraction of the player width.
*
* Returns the corresponding elapsed time as a number of seconds.
*/
setProgressByFraction(fraction) {
const progressWidth = (fraction
* this._progressContainer.clientWidth);
this._progressBar.style.width = progressWidth + 'px';
return fraction * this._controlSource.duration;
}
/*
* Set the width of the progress bar.
*
* The arg 'absoluteXPosition' gives the desired width of the bar as
* a viewport-global X coordinate.
*
* Returns the corresponding elapsed time as a number of seconds.
*/
setProgressByPosition(absoluteXPosition) {
const bounds = this._progressContainer.getBoundingClientRect();
const xRel = absoluteXPosition - bounds.x;
const fraction = xRel / this._progressContainer.clientWidth;
return this.setProgressByFraction(fraction);
}
/*
* Set the width of the progress bar.
*
* The arg 'elapsedTime' gives the desired width of the bar as a
* number of seconds since start.
*/
setProgressByTime(elapsedTime) {
this.setProgressByFraction(elapsedTime
/ this._controlSource.duration);
}
/*
* Switch icon and text on a button to its alternative text/icon.
*