两行代码实现,音乐波动条纹

优势

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>

谢谢您的阅读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值