AudioContext实现音乐盒
- 时间:2021年5月13日
- 人员:杨标
- 名称:AudioContext实现音乐盒动态效果
- 技术点:AudioContext API,Audio使用,canvas的使用
效果图
案例说明
通过AudioContext 的API来读取音乐音频数据,然后通过如上图所示的东西展示出来
本案列主要使用AudioContext
的API,Canvas
画布内容,Uint8Array
等技术点
代码
index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>audioContext Demo</title>
<style>
#c1 {
background-color: #000;
display: block;
margin: auto;
}
</style>
</head>
<body>
<canvas id="c1" width="1440" height="600"></canvas>
<button type="button" id="btnStart">开始</button>
<button type="button" id="btnStop">结束</button>
</body>
<script src="./js/index.js"></script>
</html>
index.js
class Rectangle {
constructor(index) {
this.index = index;
let baseWidth = 1440 / 30;
this.x = index * baseWidth;
this.width = baseWidth - 5;
this.redY = 600 - 12;
}
setPower(bili, powerArr) {
this.power = powerArr[parseInt(1440 / 30 * this.index * bili)];
this.height = 600 * this.power / 255;
this.y = 600 - this.height;
}
/**
*
* @param {CanvasRenderingContext2D} ctx
*/
draw(ctx) {
let baseHeight = 12;
let rectCount = this.height / baseHeight;
if (this.redY > this.y) {
this.redY = this.y - 12;
}
else {
this.redY += 2;
if (this.redY > 600 - 12) {
this.redY = 600 - 12;
}
}
ctx.save();
ctx.fillStyle = "red";
ctx.fillRect(this.x, this.redY, this.width, baseHeight - 3);
ctx.restore();
for (let i = 0; i < rectCount; i++) {
ctx.fillRect(this.x, this.y + i * baseHeight, this.width, baseHeight - 3);
}
}
}
let btnStart = document.getElementById("btnStart");
let btnStop = document.getElementById("btnStop");
/**
* @type {HTMLCanvasElement}
*/
let c1 = document.getElementById("c1");
let ctx = c1.getContext("2d");
let grd = ctx.createLinearGradient(0, 0, 0, 600);
grd.addColorStop(0, "red");
grd.addColorStop(0.5, "yellow");
grd.addColorStop(1, "#00E800");
ctx.fillStyle = grd;
let rt_array = new Array();
for (let i = 0; i < 30; i++) {
let rect = new Rectangle(i);
rt_array.push(rect);
}
let AC = new AudioContext();
let analyser = AC.createAnalyser();
let gainNode = AC.createGain();
gainNode.gain.value = 1;
let audio = document.createElement("audio");
audio.src = "./assets/music2.mp3";
audio.load();
let audioSource = AC.createMediaElementSource(audio);
btnStart.onclick = function () {
audioSource.connect(analyser);
analyser.connect(gainNode);
gainNode.connect(AC.destination);
audio.play();
setInterval(() => {
ctx.clearRect(0, 0, 1440, 600);
let musicBufferArray = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(musicBufferArray);
let arr = Array.prototype.slice.call(musicBufferArray);
let bili = arr.length / c1.width;
for (let i = 0; i < rt_array.length; i++) {
let rt = rt_array[i];
rt.setPower(bili, arr);
rt.draw(ctx);
}
}, 1000 / 60);
}
btnStop.onclick = function () {
audio.pause();
audioSource.disconnect(analyser);
analyser.disconnect(gainNode);
gainNode.disconnect(AC.dispatchEvent);
}
//记录时间值的变化
audio.ontimeupdate = function (event) {
console.log(event.target.currentTime);
}
评论区