56 lines
2.1 KiB
JavaScript
56 lines
2.1 KiB
JavaScript
import { useRef, useEffect } from "react";
|
|
import useSize from "./useSize";
|
|
|
|
const animateBars = (analyser, canvas, canvasCtx, dataArray, bufferLength) => {
|
|
analyser.getByteFrequencyData(dataArray)
|
|
canvasCtx.fillStyle = "#000"
|
|
const HEIGHT = canvas.height / 2
|
|
var barWidth = Math.ceil(canvas.width / bufferLength) * 2.5
|
|
let barHeight
|
|
let x = 0
|
|
for (var i = 0; i < bufferLength; i++) {
|
|
barHeight = (dataArray[i] / 255) * HEIGHT
|
|
const blueShade = Math.floor((dataArray[i] / 255) * 4) // generate a shade of blue based on the audio input
|
|
const blueHex = ["#61dafb", "#5ac8fa", "#50b6f5", "#419de6"][blueShade]; // use react logo blue shades
|
|
canvasCtx.fillStyle = blueHex
|
|
canvasCtx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight)
|
|
x += barWidth + 1
|
|
}
|
|
},
|
|
WaveForm = ({ analyzerData }) => {
|
|
const canvasRef = useRef(null),
|
|
{ dataArray, analyzer, bufferLength } = analyzerData,
|
|
[width, height] = useSize(),
|
|
draw = (dataArray, analyzer, bufferLength) => {
|
|
const canvas = canvasRef.current
|
|
if (!canvas || !analyzer) return
|
|
const canvasCtx = canvas.getContext("2d"),
|
|
animate = () => {
|
|
requestAnimationFrame(animate)
|
|
// eslint-disable-next-line no-self-assign
|
|
canvas.width = canvas.width
|
|
canvasCtx.translate(0, canvas.offsetHeight / 2)
|
|
animateBars(analyzer, canvas, canvasCtx, dataArray, bufferLength)
|
|
}
|
|
animate()
|
|
}
|
|
useEffect(() => {
|
|
draw(dataArray, analyzer, bufferLength)
|
|
}, [dataArray, analyzer, bufferLength])
|
|
return (
|
|
<canvas
|
|
style={{
|
|
position: "absolute",
|
|
top: "0",
|
|
left: "0",
|
|
zIndex: "-10"
|
|
}}
|
|
ref={canvasRef}
|
|
width={width}
|
|
height={height}
|
|
/>
|
|
)
|
|
}
|
|
|
|
export default WaveForm
|