优势
1、利用傅里叶转换准确转换波纹
2、参数直接传入一个有宽高的盒子和adio即可使用。
3、复制main.js即可使用
源码
main.js
class Adio_ripple{
/**
* @param {Element} canvas_box_dom -盒子
* @param {Element} audio_dom -audio播放器
* @param {String} color -条纹颜色
*/
constructor(canvas_box_dom,audio_dom,color='rgb(25, 209, 255)'){
this.canvas_box_dom=canvas_box_dom
this.color=color
this.can=document.createElement('canvas')
this.adio=audio_dom
this.xan=this.can.getContext('2d')
this.onit=false
this.analy_data_arr
this.analy
}
create_cont(){
this.adio.onplay=()=>{
this.init().then(()=>{
this.draw()
})
}
}
init(){
this.canvas_box_dom.appendChild(this.can)
this.can.width= this.canvas_box_dom.style.width.slice(0,-2)
this.can.height= this.canvas_box_dom.style.height.slice(0,-2)
let adio_context=new AudioContext()
let adio_pronode=adio_context.createMediaElementSource(this.adio)
this.analy= adio_context.createAnalyser()//创建分析器节点
this.analy.fftSize=512//设置分析器窗口大小
this.analy_data_arr=new Uint8Array(512/2)//用于接收分析器的数据,参数是长度
adio_pronode.connect(this.analy)//将音频源节点连接到分析器节点 analy.connect(adio_context.destination)
this.analy.connect(adio_context.destination) //将分析器节点连接到输出设备
this.onit=true
return new Promise((y,n)=>{
y('ok')
})
}
draw(){
if(!this.onit){
return
}
requestAnimationFrame(()=>{this.draw.bind(this)()})//这一帧绘制完之后,再执行draw继续绘制
this.xan.clearRect(0,0,this.can.width,this.can.height)//清除画布
this.analy.getByteFrequencyData(this.analy_data_arr)//将分析器的数据放入数组中
let lenght=this.analy_data_arr.length
let bar_width=this.can.width / lenght /2 //计算矩形的宽
for(let starts=0;starts<lenght;starts+=1){
let data=this.analy_data_arr[starts]
let bar_height=data / 255 *this.can.height//计算矩形高
this.xan.fillStyle=this.color
let x1=starts*bar_width+this.can.width/2+starts*1//计算右边矩形x坐标
let x2=(lenght-starts)*bar_width-starts*1//计算左边x的坐标
this.xan.fillRect(x1,this.can.height-bar_height,bar_width,bar_height)
this.xan.fillRect(x2,this.can.height-bar_height,bar_width,bar_height)
}
}
}
使用示例
index.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0px;
border: 0px;
padding: 0px;
}
body{
width: 100vw;
}
</style>
</head>
<body>
<div id="app" style="width: 500px;height: 300px;border: 3px solid;background-color: aqua;"></div>
<audio src="./夏夜.mp3" style="width: 50vh;height: 10vh;margin: auto;" controls id="audio"></audio>
</body>
<script src="./main.js"></script>
<script>
let f=new Adio_ripple(document.querySelector('#app'),document.querySelector('#audio'),'red')
f.create_cont()
</script>
</html>
<script>
谢谢您的阅读