/**
* @file load-progress-bar.js
*/
import Component from '../../component.js' ;
import * as Dom from '../../utils/dom.js' ;
import clamp from '../../utils/clamp' ;
import document from 'global/document' ;
// obtenir le pourcentage de largeur d'un temps par rapport au total fin
const percentify = (time, end) => clamp((time / end) * 100, 0, 100).toFixed(2) + '%' ;
/**
* Affiche l'état d'avancement du chargement
*
* @extends Component
*/
class LoadProgressBar extends Component {
/**
* Crée une instance de cette classe.
*
* @param {Player} player
* Le `Player` auquel cette classe doit être attachée.
*
* @param {Objet} [options]
* La mémoire clé/valeur des options du lecteur.
*/
constructor(player, options) {
super(player, options) ;
this.partEls_ = [] ;
this.on(player, 'progress', (e) => this.update(e)) ;
}
/**
* Créer l'élément DOM du `Composant`
*
* @return {Element}
* L'élément qui a été créé.
*/
createEl() {
const el = super.createEl('div', {className : 'vjs-load-progress'}) ;
const wrapper = Dom.createEl('span', {className : 'vjs-control-text'}) ;
const loadedText = Dom.createEl('span', {textContent : this.localize('Loaded')}) ;
const separator = document.createTextNode(' : ') ;
this.percentageEl_ = Dom.createEl('span', {
className : 'vjs-control-text-loaded-percentage',
textContent : '0%'
}) ;
el.appendChild(wrapper) ;
wrapper.appendChild(loadedText) ;
wrapper.appendChild(separator) ;
wrapper.appendChild(this.percentageEl_) ;
return el ;
}
dispose() {
this.partEls_ = null ;
this.percentageEl_ = null ;
super.dispose() ;
}
/**
* Mise à jour de la barre de progression
*
* @param {EventTarget~Event} [event]
* L'événement `progress` qui a provoqué l'exécution de cette fonction.
*
* @listens Player#progress
*/
update(event) {
this.requestNamedAnimationFrame('LoadProgressBar#update', () => {
const liveTracker = this.player_.liveTracker ;
const buffered = this.player_.buffered() ;
const duration = (liveTracker && liveTracker.isLive()) ? liveTracker.seekableEnd() : this.player_.duration() ;
const bufferedEnd = this.player_.bufferedEnd() ;
const children = this.partEls_ ;
const percent = percentify(bufferedEnd, duration) ;
if (this.percent_ !== percent) {
// mettre à jour la largeur de la barre de progression
this.el_.style.width = percent ;
// mettre à jour le texte du contrôle
Dom.textContent(this.percentageEl_, percent) ;
this.percent_ = percent ;
}
// ajouter des éléments enfants pour représenter les différentes plages de temps mises en mémoire tampon
for (let i = 0 ; i < buffered.length ; i++) {
const start = buffered.start(i) ;
const end = buffered.end(i) ;
let part = children[i] ;
if (!part) {
part = this.el_.appendChild(Dom.createEl()) ;
enfants[i] = partie ;
}
// ne mettre à jour qu'en cas de changement
if (part.dataset.start === start && part.dataset.end === end) {
continuer ;
}
part.dataset.start = start ;
part.dataset.end = end ;
// fixer le pourcentage en fonction de la largeur de la barre de progression (bufferedEnd)
part.style.left = percentify(start, bufferedEnd) ;
part.style.width = percentify(end - start, bufferedEnd) ;
}
// supprimer les éléments inutilisés de la plage tamponnée
for (let i = children.length ; i > buffered.length ; i--) {
this.el_.removeChild(children[i - 1]) ;
}
children.length = buffered.length ;
}) ;
}
}
Component.registerComponent('LoadProgressBar', LoadProgressBar) ;
export default LoadProgressBar ;