1. 1 : /**
  2. 2 : * @file volume-level-tooltip.js
  3. 3 : */
  4. 4 : import Component from '../../component';
  5. 5 : import * as Dom from '../../utils/dom.js';
  6. 6 : import * as Fn from '../../utils/fn.js';
  7. 7 :
  8. 8 : /**
  9. 9 : * Volume level tooltips display a volume above or side by side the volume bar.
  10. 10 : *
  11. 11 : * @extends Component
  12. 12 : */
  13. 13 : class VolumeLevelTooltip extends Component {
  14. 14 :
  15. 15 : /**
  16. 16 : * Creates an instance of this class.
  17. 17 : *
  18. 18 : * @param {Player} player
  19. 19 : * The {@link Player} that this class should be attached to.
  20. 20 : *
  21. 21 : * @param {Object} [options]
  22. 22 : * The key/value store of player options.
  23. 23 : */
  24. 24 : constructor(player, options) {
  25. 25 : super(player, options);
  26. 26 : this.update = Fn.throttle(Fn.bind(this, this.update), Fn.UPDATE_REFRESH_INTERVAL);
  27. 27 : }
  28. 28 :
  29. 29 : /**
  30. 30 : * Create the volume tooltip DOM element
  31. 31 : *
  32. 32 : * @return {Element}
  33. 33 : * The element that was created.
  34. 34 : */
  35. 35 : createEl() {
  36. 36 : return super.createEl('div', {
  37. 37 : className: 'vjs-volume-tooltip'
  38. 38 : }, {
  39. 39 : 'aria-hidden': 'true'
  40. 40 : });
  41. 41 : }
  42. 42 :
  43. 43 : /**
  44. 44 : * Updates the position of the tooltip relative to the `VolumeBar` and
  45. 45 : * its content text.
  46. 46 : *
  47. 47 : * @param {Object} rangeBarRect
  48. 48 : * The `ClientRect` for the {@link VolumeBar} element.
  49. 49 : *
  50. 50 : * @param {number} rangeBarPoint
  51. 51 : * A number from 0 to 1, representing a horizontal/vertical reference point
  52. 52 : * from the left edge of the {@link VolumeBar}
  53. 53 : *
  54. 54 : * @param {boolean} vertical
  55. 55 : * Referees to the Volume control position
  56. 56 : * in the control bar{@link VolumeControl}
  57. 57 : *
  58. 58 : */
  59. 59 : update(rangeBarRect, rangeBarPoint, vertical, content) {
  60. 60 : if (!vertical) {
  61. 61 : const tooltipRect = Dom.getBoundingClientRect(this.el_);
  62. 62 : const playerRect = Dom.getBoundingClientRect(this.player_.el());
  63. 63 : const volumeBarPointPx = rangeBarRect.width * rangeBarPoint;
  64. 64 :
  65. 65 : if (!playerRect || !tooltipRect) {
  66. 66 : return;
  67. 67 : }
  68. 68 :
  69. 69 : const spaceLeftOfPoint = (rangeBarRect.left - playerRect.left) + volumeBarPointPx;
  70. 70 : const spaceRightOfPoint = (rangeBarRect.width - volumeBarPointPx) +
  71. 71 : (playerRect.right - rangeBarRect.right);
  72. 72 : let pullTooltipBy = tooltipRect.width / 2;
  73. 73 :
  74. 74 : if (spaceLeftOfPoint < pullTooltipBy) {
  75. 75 : pullTooltipBy += pullTooltipBy - spaceLeftOfPoint;
  76. 76 : } else if (spaceRightOfPoint < pullTooltipBy) {
  77. 77 : pullTooltipBy = spaceRightOfPoint;
  78. 78 : }
  79. 79 :
  80. 80 : if (pullTooltipBy < 0) {
  81. 81 : pullTooltipBy = 0;
  82. 82 : } else if (pullTooltipBy > tooltipRect.width) {
  83. 83 : pullTooltipBy = tooltipRect.width;
  84. 84 : }
  85. 85 :
  86. 86 : this.el_.style.right = `-${pullTooltipBy}px`;
  87. 87 : }
  88. 88 : this.write(`${content}%`);
  89. 89 : }
  90. 90 :
  91. 91 : /**
  92. 92 : * Write the volume to the tooltip DOM element.
  93. 93 : *
  94. 94 : * @param {string} content
  95. 95 : * The formatted volume for the tooltip.
  96. 96 : */
  97. 97 : write(content) {
  98. 98 : Dom.textContent(this.el_, content);
  99. 99 : }
  100. 100 :
  101. 101 : /**
  102. 102 : * Updates the position of the volume tooltip relative to the `VolumeBar`.
  103. 103 : *
  104. 104 : * @param {Object} rangeBarRect
  105. 105 : * The `ClientRect` for the {@link VolumeBar} element.
  106. 106 : *
  107. 107 : * @param {number} rangeBarPoint
  108. 108 : * A number from 0 to 1, representing a horizontal/vertical reference point
  109. 109 : * from the left edge of the {@link VolumeBar}
  110. 110 : *
  111. 111 : * @param {boolean} vertical
  112. 112 : * Referees to the Volume control position
  113. 113 : * in the control bar{@link VolumeControl}
  114. 114 : *
  115. 115 : * @param {number} volume
  116. 116 : * The volume level to update the tooltip to
  117. 117 : *
  118. 118 : * @param {Function} cb
  119. 119 : * A function that will be called during the request animation frame
  120. 120 : * for tooltips that need to do additional animations from the default
  121. 121 : */
  122. 122 : updateVolume(rangeBarRect, rangeBarPoint, vertical, volume, cb) {
  123. 123 : this.requestNamedAnimationFrame('VolumeLevelTooltip#updateVolume', () => {
  124. 124 : this.update(rangeBarRect, rangeBarPoint, vertical, volume.toFixed(0));
  125. 125 : if (cb) {
  126. 126 : cb();
  127. 127 : }
  128. 128 : });
  129. 129 : }
  130. 130 : }
  131. 131 :
  132. 132 : Component.registerComponent('VolumeLevelTooltip', VolumeLevelTooltip);
  133. 133 : export default VolumeLevelTooltip;