私聊免费获取源码:
MJ682517
1、音频一定要正确,网络音频播放无声音,本地音频才可以
2、酷狗下载的kgma格式音频不支持
3、目前试了一下本地的mp3格式可以正常播放
4、代码解析,都在代码中了
<body class="bc_333">
<div class="box d_f fd_c jc_c">
<canvas>canvas>
<hr class="w_100_ bc_dcdcdc h_1 b_n" />
<audio class="w_86_ m_a" controls loop src="./1.mp3">audio>
<div class="m_t_10">
<div id="idIntervalBtn" class="w_50_ m_lr_a d_f jc_sb">div>
<div id="idClothCoverBtn" class="w_50_ m_lr_a d_f jc_sb m_t_10">div>
div>
div>
body>
// 全局变量
let audioEle = document.querySelector('audio'),
cvs = document.querySelector('canvas'),
ctx = cvs.getContext('2d'),
// 控制初始化
isInit = false,
dataArray = undefined,
analyser = undefined,
animation = undefined,
// 按钮操作
interval = 2,
// 条形粗细
clothCover = 1024;
// 初始化页面
initPage();
function initPage() {
let intervalEl = '',
clothCoverEl = '';
for (let i = 2; i < 9; i++) intervalEl += `" οnclick="handleInterval(event, ${i})">${i}`;
for (let i = 9; i < 12; i++) {
let val = 2 ** i;
clothCoverEl += `" οnclick="handleClothCover(${val})">${val}`;
}
idIntervalBtn.innerHTML = intervalEl;
idClothCoverBtn.innerHTML = clothCoverEl;
}
// 初花canvas的尺寸
initCvs();
function initCvs() {
cvs.width = window.innerWidth * devicePixelRatio;
cvs.height = (window.innerHeight / 1.5) * devicePixelRatio;
}
// 播放
audioEle.onplay = handlePlay;
function handlePlay() {
if (isInit) {
analyser.fftSize = clothCover;
return draw();
}
// 初始化
// 创建音频上下文
let audCtx = new AudioContext(),
// 创建音频源节点
source = audCtx.createMediaElementSource(audioEle);
// 分析器节点
analyser = audCtx.createAnalyser();
// 设置变换窗口大小
// 默认值为2048,必须是2的n次幂
// 数值越大,则得到的值与音频频率更接近
analyser.fftSize = clothCover;
// 创建数组,用于接收分析器节点的分析数据
// 类型化数组
// 每一项代表一个字节
// 表示数组里面的每一项是一个无符号的8位整数
// new Uint8Array(512 / 2);
// frequencyBinCount属性会自动把值除以2
dataArray = new Uint8Array(analyser.frequencyBinCount);
// 音频源与分析器连接
source.connect(analyser);
// 分析器连接到输出设备(输出声音)
analyser.connect(audCtx.destination);
isInit = true;
draw();
}
// 暂停
audioEle.onpause = function () {
cancelAnimationFrame(animation);
}
// 把分析出的波形绘制到canvas
function draw() {
// 类似递归(循环绘制)
animation = requestAnimationFrame(draw);
let { width, height } = cvs,
len = 0,
barWidth = 0,
gradient = undefined;
// 清空画布
ctx.clearRect(0, 0, width, height);
if (!isInit) return console.log('未初始化!');
// 让分析器节点分析出数据到数组中
analyser.getByteFrequencyData(dataArray);
len = dataArray.length / 2.5;
barWidth = width / len / 2;
// ctx.fillStyle = '#78c5f7';
// 创建线性渐变对象(横向渐变)
gradient = ctx.createLinearGradient(0, 0, width, 0);
// 添加渐变色段
gradient.addColorStop(0, hexadecimalColor());
gradient.addColorStop(0.5, hexadecimalColor());
gradient.addColorStop(1, hexadecimalColor());
ctx.fillStyle = gradient;
for (let i = 0; i < len; i++) {
let data = dataArray[i],
barHeight = data / 255 * height,
// / 2 波形图取一半
x1 = i * barWidth + width / 2,
// 波形图另一半
x2 = width / 2 - (i + 1) * barWidth,
// x1和x2为对称图形
// 只是x轴坐标不同
// y轴一样
y = height - barHeight;
// - 2 让每个条之间有缝隙
// 右半边
ctx.fillRect(x1, y, barWidth - interval, barHeight);
// 左半边
ctx.fillRect(x2, y, barWidth - interval, barHeight);
}
}
// 随机十六进制颜色
function hexadecimalColor() {
let str = '0123456789abcdef',
len = str.length,
shuffleArray = undefined,
arr = [],
color = '#';
str = str.split('');
shuffleArray = (arr) => arr.sort(() => Math.random() - 0.5);
arr = shuffleArray(str);
str = arr.toString();
str = str.replace(/,/g, '');
for (let i = 0; i < 6; i++) {
let j = Math.floor(Math.random() * len);
color += str[j];
}
return color;
}
// 间隔设置
function handleInterval(event, value) {
let el = document.querySelector('#idIntervalBtn').childNodes;
for (let i = 0; i < el.length; i++) {
const val = el[i].textContent;
if (value == val) {
event.target.classList.add('color_blue');
} else {
el[i].classList.remove('color_blue');
}
}
interval = value;
}
// 条形粗细
function handleClothCover(value) {
let el = document.querySelector('#idClothCoverBtn').childNodes;
for (let i = 0; i < el.length; i++) {
const val = el[i].textContent;
if (value == val) {
event.target.classList.add('color_blue');
} else {
el[i].classList.remove('color_blue');
}
}
clothCover = value;
handlePlay();
}
.bc_333 {
background-color: #333333;
}
.bc_dcdcdc {
background-color: #dcdcdc;
}
.h_1 {
height: 1px;
}
.b_n {
border: none;
}
.c_p {
cursor: pointer;
}
.w_50_ {
width: 50%;
}
.w_86_ {
width: 86%;
}
.w_100_ {
width: 100%;
}
.d_f {
display: flex;
}
.fd_c {
flex-direction: column;
}
.jc_sb {
justify-content: space-between;
}
.jc_c {
justify-content: center;
}
.m_a {
margin: auto;
}
.m_lr_a {
margin-left: auto;
margin-right: auto;
}
.m_t_10 {
margin-top: 10px;
}
.w_68 {
width: 68px;
}
.radius_4 {
border-radius: 4;
}
.radius_6 {
border-radius: 6;
}
.color_blue {
color: #0000ff;
}
.fw_700 {
font-weight: 700;
}