/**
* @file time-tooltip.js
*/
import Component from '../../component' ;
import * as Dom from '../../utils/dom.js' ;
import formatTime from '../../utils/format-time.js' ;
import * as Fn from '../../utils/fn.js' ;
/**
* Les infobulles temporelles affichent une durée au-dessus de la barre de progression.
*
* @extends Component
*/
class TimeTooltip extends Component {
/**
* Crée une instance de cette classe.
*
* @param {Player} player
* Le {@link 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.update = Fn.throttle(Fn.bind(this, this.update), Fn.UPDATE_REFRESH_INTERVAL) ;
}
/**
* Créer l'élément DOM de l'info-bulle sur l'heure
*
* @return {Element}
* L'élément qui a été créé.
*/
createEl() {
return super.createEl('div', {
className : 'vjs-time-tooltip'
}, {
aria-hidden" : "true" (vrai)
}) ;
}
/**
* Met à jour la position de l'info-bulle de l'heure par rapport à la `SeekBar`.
*
* @param {Object} seekBarRect
* Le `ClientRect` de l'élément {@link SeekBar}.
*
* @param {number} seekBarPoint
* Un nombre compris entre 0 et 1, représentant un point de référence horizontal
* à partir du bord gauche de la {@link SeekBar}
*/
update(seekBarRect, seekBarPoint, content) {
const tooltipRect = Dom.findPosition(this.el_) ;
const playerRect = Dom.getBoundingClientRect(this.player_.el()) ;
const seekBarPointPx = seekBarRect.width * seekBarPoint ;
// ne rien faire si l'un ou l'autre rect n'est pas disponible
// par exemple, si le joueur n'est pas dans le DOM pour le test
if (!playerRect || !tooltipRect) {
retour ;
}
// C'est l'espace à gauche du `seekBarPoint` disponible à l'intérieur des limites
// du joueur. Nous calculons tout écart entre le bord gauche du joueur
// et le bord gauche de la `SeekBar` et ajoutez le nombre de pixels dans le champ
// Rechercher la barre avant d'atteindre le point de recherche (`seekBarPoint`)
const spaceLeftOfPoint = (seekBarRect.left - playerRect.left) + seekBarPointPx ;
// C'est l'espace à droite du `seekBarPoint` disponible à l'intérieur des limites
// du joueur. Nous calculons le nombre de pixels à partir du `seekBarPoint`
// au bord droit de la `SeekBar` et ajoutez-y l'écart entre la `SeekBar` et le bord droit de la `SeekBar`
// bord droit de la `SeekBar` et du lecteur.
const spaceRightOfPoint = (seekBarRect.width - seekBarPointPx) +
(playerRect.right - seekBarRect.right) ;
// Il s'agit du nombre de pixels dont l'infobulle devra être tirée
// plus à droite pour le centrer sur le `seekBarPoint`.
let pullTooltipBy = tooltipRect.width / 2 ;
// Ajuster la distance `pullTooltipBy` vers la gauche ou la droite en fonction de
// les résultats des calculs d'espace ci-dessus.
if (spaceLeftOfPoint < pullTooltipBy) {
pullTooltipBy += pullTooltipBy - spaceLeftOfPoint ;
} else if (spaceRightOfPoint < pullTooltipBy) {
pullTooltipBy = spaceRightOfPoint ;
}
// En raison de l'imprécision des calculs basés sur les décimales/ratios et de la variation des taux d'intérêt, le système d'échange de quotas d'émission a été modifié
// comportements d'arrondi, il y a des cas où l'ajustement de l'espacement n'est pas correct
// d'un ou deux pixels. Cela ajoute une assurance à ces calculs.
if (pullTooltipBy < 0) {
pullTooltipBy = 0 ;
} else if (pullTooltipBy > tooltipRect.width) {
pullTooltipBy = tooltipRect.width ;
}
// empêche les petites fluctuations de largeur dans les 0,4px de
// modifier la valeur ci-dessous.
// Cela permet d'éviter le jeu en direct
// l'info-bulle sur le temps de progression n'est pas gérable
pullTooltipBy = Math.round(pullTooltipBy) ;
this.el_.style.right = `-${pullTooltipBy}px` ;
this.write(content) ;
}
/**
* Inscrire l'heure dans l'élément DOM de l'infobulle.
*
* @param {string} content
* L'heure formatée pour l'infobulle.
*/
write(content) {
Dom.textContent(this.el_, content) ;
}
/**
* Met à jour la position de l'info-bulle de l'heure par rapport à la `SeekBar`.
*
* @param {Object} seekBarRect
* Le `ClientRect` de l'élément {@link SeekBar}.
*
* @param {number} seekBarPoint
* Un nombre compris entre 0 et 1, représentant un point de référence horizontal
* à partir du bord gauche de la {@link SeekBar}
*
* @param {number} time
* Heure de mise à jour de l'infobulle, non utilisée lors de la lecture en direct
*
* @param {Fonction} cb
* Une fonction qui sera appelée pendant l'image d'animation de la demande
* pour les infobulles qui ont besoin d'animations supplémentaires par rapport à l'animation par défaut
*/
updateTime(seekBarRect, seekBarPoint, time, cb) {
this.requestNamedAnimationFrame('TimeTooltip#updateTime', () => {
laisser le contenu ;
const duration = this.player_.duration() ;
if (this.player_.liveTracker && this.player_.liveTracker.isLive()) {
const liveWindow = this.player_.liveTracker.liveWindow() ;
const secondsBehind = liveWindow - (seekBarPoint * liveWindow) ;
content = (secondsBehind < 1 ? '' : '-') + formatTime(secondsBehind, liveWindow) ;
} else {
content = formatTime(time, duration) ;
}
this.update(seekBarRect, seekBarPoint, content) ;
if (cb) {
cb() ;
}
}) ;
}
}
Component.registerComponent('TimeTooltip', TimeTooltip) ;
exporter l'info-bulle par défaut TimeTooltip ;