新增第209个小实例:音频可视化

This commit is contained in:
DESKTOP-BM6RJU5\wyanh 2023-02-28 16:31:09 +08:00
parent c64138afaf
commit 04a2b32549
4 changed files with 115 additions and 0 deletions

View File

@ -216,6 +216,7 @@
206. HTML5+CSS3小实例人物介绍卡片2.0
207. HTML5+CSS3小实例弹出式悬停效果
208. HTML5+CSS3+JS小实例五彩纸屑礼花筒
209. HTML5+CSS3+JS小实例音频可视化
#### 赞赏作者
![image](https://gitee.com/wyanhui02/html_css_demo/raw/master/images/%E8%B5%9E%E8%B5%8F%E4%BD%9C%E8%80%85/%E8%B5%9E%E8%B5%8F%E7%A0%81.jpg)

25
code/209/209.css Normal file
View File

@ -0,0 +1,25 @@
*{
margin: 0;
padding: 0;
}
body{
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
background-color: #000;
}
canvas{
width: 100%;
height: 100vh;
}
audio{
position: absolute;
top: 20px;
right: 20px;
opacity: 0.15;
transition: opacity 0.5s;
}
audio:hover{
opacity: 1;
}

16
code/209/209.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="zh-CN">
<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>音频可视化</title>
<link rel="stylesheet" href="209.css">
</head>
<body>
<canvas></canvas>
<audio src="/mp3/夜曲.mp3" controls></audio>
</body>
</html>
<script src="209.js"></script>

73
code/209/209.js Normal file
View File

@ -0,0 +1,73 @@
// 要操作的元素
const audio=document.querySelector('audio');
const cvs=document.querySelector('canvas');
const ctx=cvs.getContext('2d');
// 初始化画布
function initCvs(){
cvs.width=window.innerWidth * devicePixelRatio;
cvs.height=(window.innerHeight / 2) * devicePixelRatio;
}
initCvs();
// 是否已初始化
let isInit=false;
// 数组,用于接收分析器节点的分析数据
let dataArray;
// 分析器节点
let analyser;
// 音频播放事件
audio.onplay=function(){
// 判断是否初始化
if(isInit){
return;
}
// 开始初始化
// 创建音频上下文
const audioCtx=new AudioContext();
// 创建音频源节点
const source=audioCtx.createMediaElementSource(audio);
// 创建分析器节点
analyser=audioCtx.createAnalyser();
analyser.fftSize=512;
// 接收分析器节点的分析数据
dataArray=new Uint8Array(analyser.frequencyBinCount);
source.connect(analyser);
analyser.connect(audioCtx.destination);
// 已初始化
isInit=true;
}
// 把分析出来的波形绘制到canvas上
function draw(){
// 逐帧绘制
requestAnimationFrame(draw);
// 接下来清空画布
const { width, height } = cvs;
ctx.clearRect(0,0,width,height);
if(!isInit){
return;
}
// 让分析器节点分析出数据到数组中
analyser.getByteFrequencyData(dataArray);
const len=dataArray.length / 2; //条的数量,取一半,前半部分(低频范围就好,高频部分人耳几乎听不到,看不到波形)
const barWidth=width / len / 2; //条的宽度
ctx.fillStyle='#e0f9b5';
// 循环绘制
for(let i=0;i<len;i++){
const data=dataArray[i];
const barHeight=(data / 255) * height; //条的高度
const x1=i * barWidth + width / 2; //右边区域中条的x坐标
const x2=width / 2 - (i + 1) * barWidth; //左边区域中条的x坐标 镜像
const y=height - barHeight; //条的y坐标
ctx.fillRect(x1,y,barWidth - 2,barHeight); //填充右边区域
ctx.fillRect(x2,y,barWidth - 2,barHeight); //填充左边区域
}
}
draw();