react-volume-meter
Version:
A volume meter React component
129 lines (109 loc) • 3.78 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var draw = function draw(width, height, canvasCtx, prevVolume, volume, maxVolume) {
var vol = Math.max(volume, prevVolume * 0.95);
canvasCtx.clearRect(0, 0, width, height);
for (var i = 0; i < 5; i++) {
if (i === 4 && maxVolume < vol) {
canvasCtx.fillStyle = 'red';
} else if ((i + 1) * (maxVolume / 5) < vol) {
canvasCtx.fillStyle = 'green';
} else {
canvasCtx.fillStyle = 'grey';
}
var x = width * i / 5;
var y = height * 0.6 - height * i * 0.15;
canvasCtx.fillRect(x, y, width / 6, height - y);
if (vol < maxVolume && i * 10 < vol) {
canvasCtx.fillStyle = 'green';
canvasCtx.fillRect(x, y, vol % (maxVolume / 5) / (maxVolume / 5) * (width / 6), height - y);
}
}
};
var VolumeMeter = _react2.default.createClass({
displayName: 'VolumeMeter',
getVolume: function getVolume() {
this.analyser.getByteFrequencyData(this.array);
var length = this.array.length;
var total = 0;
for (var i = 0; i < length; i++) {
total += this.array[i];
}
return total / length;
},
start: function start() {
var _this = this;
var _props = this.props;
var width = _props.width;
var height = _props.height;
var maxVolume = _props.maxVolume;
var canvasCtx = this.refs.canvas.getContext('2d');
var prevVolume = 0;
var drawLoop = function drawLoop() {
if (_this.analyser.ended) return;
var volume = _this.getVolume();
draw(width, height, canvasCtx, volume, prevVolume, maxVolume || 50);
prevVolume = volume;
_this.rafId = window.requestAnimationFrame(drawLoop);
};
drawLoop();
},
stop: function stop() {
var _props2 = this.props;
var width = _props2.width;
var height = _props2.height;
var maxVolume = _props2.maxVolume;
var canvasCtx = this.refs.canvas.getContext('2d');
window.cancelAnimationFrame(this.rafId);
draw(width, height, canvasCtx, 0, 0, maxVolume || 50);
},
componentDidMount: function componentDidMount() {
var _props3 = this.props;
var width = _props3.width;
var height = _props3.height;
var maxVolume = _props3.maxVolume;
var canvasCtx = this.refs.canvas.getContext('2d');
draw(width, height, canvasCtx, 0, 0, maxVolume || 50);
},
componentWillUpdate: function componentWillUpdate(nextProps) {
if (!this.props.src && nextProps.src) {
var audioContext = nextProps.audioContext;
var src = nextProps.src;
this.analyser = audioContext.createAnalyser();
src.connect(this.analyser);
this.array = new Uint8Array(this.analyser.frequencyBinCount);
}
},
componentDidUpdate: function componentDidUpdate(prevProps) {
if (this.props.command && this.props.command !== 'none' && prevProps.command !== this.props.command) {
this[this.props.command]();
}
},
render: function render() {
var _props4 = this.props;
var width = _props4.width;
var height = _props4.height;
var style = _props4.style;
return _react2.default.createElement('canvas', {
ref: 'canvas',
width: width,
height: height,
style: style
});
},
propTypes: {
command: _react.PropTypes.oneOf(['start', 'stop', 'none']),
audioContext: _react.PropTypes.object.isRequired,
src: _react.PropTypes.object,
width: _react.PropTypes.number.isRequired,
height: _react.PropTypes.number.isRequired,
maxVolume: _react.PropTypes.number,
style: _react.PropTypes.object
}
});
exports.default = VolumeMeter;