You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AudioLevelIndicator.js 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import PropTypes from 'prop-types';
  2. import React, { Component } from 'react';
  3. /**
  4. * The number of dots to display in AudioLevelIndicator.
  5. *
  6. * IMPORTANT: AudioLevelIndicator assumes that this is an odd number.
  7. */
  8. const AUDIO_LEVEL_DOTS = 5;
  9. /**
  10. * The index of the dot that is at the direct middle of all other dots.
  11. */
  12. const CENTER_DOT_INDEX = Math.floor(AUDIO_LEVEL_DOTS / 2);
  13. /**
  14. * Creates a ReactElement responsible for drawing audio levels.
  15. *
  16. * @extends {Component}
  17. */
  18. class AudioLevelIndicator extends Component {
  19. /**
  20. * {@code AudioLevelIndicator}'s property types.
  21. *
  22. * @static
  23. */
  24. static propTypes = {
  25. /**
  26. * The current audio level to display. The value should be a number
  27. * between 0 and 1.
  28. *
  29. * @type {number}
  30. */
  31. audioLevel: PropTypes.number
  32. };
  33. /**
  34. * Implements React's {@link Component#render()}.
  35. *
  36. * @inheritdoc
  37. * @returns {ReactElement}
  38. */
  39. render() {
  40. // First make sure we are sensitive enough.
  41. const audioLevel = Math.min(this.props.audioLevel * 1.2, 1);
  42. // Let's now stretch the audio level over the number of dots we have.
  43. const stretchedAudioLevel = AUDIO_LEVEL_DOTS * audioLevel;
  44. const audioLevelDots = [];
  45. for (let i = 0; i < AUDIO_LEVEL_DOTS; i++) {
  46. const distanceFromCenter = CENTER_DOT_INDEX - i;
  47. const audioLevelFromCenter
  48. = stretchedAudioLevel - Math.abs(distanceFromCenter);
  49. const cappedOpacity = Math.min(
  50. 1, Math.max(0, audioLevelFromCenter));
  51. let className;
  52. if (distanceFromCenter === 0) {
  53. className = 'audiodot-middle';
  54. } else if (distanceFromCenter < 0) {
  55. className = 'audiodot-top';
  56. } else {
  57. className = 'audiodot-bottom';
  58. }
  59. audioLevelDots.push(
  60. <span
  61. className = { className }
  62. key = { i }
  63. style = {{ opacity: cappedOpacity }} />
  64. );
  65. }
  66. return (
  67. <span className = 'audioindicator in-react'>
  68. { audioLevelDots }
  69. </span>
  70. );
  71. }
  72. }
  73. export default AudioLevelIndicator;