This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
/**
|
||||
* The number of dots to display in AudioLevelIndicator.
|
||||
*
|
||||
* IMPORTANT: AudioLevelIndicator assumes that this is an odd number.
|
||||
*/
|
||||
const AUDIO_LEVEL_DOTS = 5;
|
||||
|
||||
/**
|
||||
* The index of the dot that is at the direct middle of all other dots.
|
||||
*/
|
||||
const CENTER_DOT_INDEX = Math.floor(AUDIO_LEVEL_DOTS / 2);
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link AudioLevelIndicator}.
|
||||
*/
|
||||
interface IProps {
|
||||
|
||||
/**
|
||||
* The current audio level to display. The value should be a number between
|
||||
* 0 and 1.
|
||||
*/
|
||||
audioLevel: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ReactElement responsible for drawing audio levels.
|
||||
*
|
||||
* @augments {Component}
|
||||
*/
|
||||
class AudioLevelIndicator extends Component<IProps> {
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
override render() {
|
||||
const { audioLevel: passedAudioLevel } = this.props;
|
||||
|
||||
// First make sure we are sensitive enough.
|
||||
const audioLevel = typeof passedAudioLevel === 'number' && !isNaN(passedAudioLevel)
|
||||
? Math.min(passedAudioLevel * 1.2, 1) : 0;
|
||||
|
||||
// Let's now stretch the audio level over the number of dots we have.
|
||||
const stretchedAudioLevel = AUDIO_LEVEL_DOTS * audioLevel;
|
||||
|
||||
const audioLevelDots = [];
|
||||
|
||||
for (let i = 0; i < AUDIO_LEVEL_DOTS; i++) {
|
||||
const distanceFromCenter = CENTER_DOT_INDEX - i;
|
||||
const audioLevelFromCenter
|
||||
= stretchedAudioLevel - Math.abs(distanceFromCenter);
|
||||
const cappedOpacity = Math.min(
|
||||
1, Math.max(0, audioLevelFromCenter));
|
||||
let className;
|
||||
|
||||
if (distanceFromCenter === 0) {
|
||||
className = 'audiodot-middle';
|
||||
} else if (distanceFromCenter < 0) {
|
||||
className = 'audiodot-top';
|
||||
} else {
|
||||
className = 'audiodot-bottom';
|
||||
}
|
||||
|
||||
audioLevelDots.push(
|
||||
<span
|
||||
className = { className }
|
||||
key = { i }
|
||||
style = {{ opacity: cappedOpacity }} />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span className = 'audioindicator in-react'>
|
||||
{ audioLevelDots }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AudioLevelIndicator;
|
||||
Reference in New Issue
Block a user