使用js写一个音乐音谱图
我们经常看到在听乐音的时候,会有音谱图随着音乐的节奏不断变化给人视觉上的享受,那么我们通过js来实现以下这个效果,下面是简单的效果图

首先我们需要有一个绘制音频的函数
function draw() { // 请求下一帧动画 animationId = requestAnimationFrame(draw);
// 获取音频频谱数据 analyser.getByteFrequencyData(dataArray);
// 清空画布 ctx.fillStyle = 'black'; ctx.fillRect(0, 0, canvas.width, canvas.height);
// 计算每个频谱条的宽度 var barWidth = (canvas.width / bufferLength) * 2.5; var barHeight; var x = 0;
// 遍历频谱数据数组,绘制频谱条 for (var i = 0; i < bufferLength; i++) { // 计算频谱条的高度 barHeight = dataArray[i] / 255 * canvas.height;
// 根据频谱条的索引值计算颜色(彩虹色) var hue = i / bufferLength * 360; ctx.fillStyle = 'hsl(' + hue + ', 100%, 50%)';
// 绘制频谱条矩形 ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
// 更新下一个频谱条的起始位置 x += barWidth + 1; }}
这个函数是用于绘制频谱图的核心部分。它使用requestAnimationFrame()方法来请求下一帧动画,并将自身作为回调函数。这样可以不断更新频谱图。
在函数内部,analyser.getByteFrequencyData(dataArray)用于获取当前的音频频谱数据,将数据存储在dataArray数组中。
然后,画布被清空,使用黑色填充整个画布。
接下来,通过计算每个频谱条的宽度,以及根据频谱数据计算每个频谱条的高度,来确定频谱条的绘制参数。
然后,使用彩虹色调的渐变来设置频谱条的颜色,颜色的HSL值根据频谱条的索引值计算。
最后,在画布上绘制每个频谱条的矩形,每个矩形之间留有间距。
通过不断调用requestAnimationFrame()方法并在每一帧更新频谱图,可以实现连续的动画效果。
document.getElementById('playButton').addEventListener('click', function() {
if (!audioContext) {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
analyser = audioContext.createAnalyser();
analyser.fftSize = 2048;
audioElement = document.createElement('audio');
audioElement.src = '1.mp3';
audioElement.controls = true;
audioElement.style.display = 'none';
document.body.appendChild(audioElement);
var source = audioContext.createMediaElementSource(audioElement);
source.connect(analyser);
analyser.connect(audioContext.destination);
bufferLength = analyser.frequencyBinCount;
dataArray = new Uint8Array(bufferLength);
}
audioElement.play();
draw();
});
document.getElementById('pauseButton').addEventListener('click', function() {
audioElement.pause();
cancelAnimationFrame(animationId);
});
当用户点击"播放"按钮时,创建一个新的AudioContext对象用于处理音频,创建一个AnalyserNode对象用于分析音频频谱。然后创建一个audio元素并将其设置为要播放的音频文件。将audio元素连接到AnalyserNode,将AnalyserNode连接到AudioContext的目标(通常是扬声器)。设置频率分析器的参数,包括FFT大小。
当用户点击"播放"按钮时,音频开始播放,并且在draw()函数中的requestAnimationFrame(draw)中调用的循环中,更新频谱数据并绘制频谱图。首先,使用analyser.getByteFrequencyData(dataArray)获取音频频谱数据。然后,通过遍历数据数组,计算每个频谱条的高度,并根据频谱条的位置在画布上绘制矩形。颜色根据频谱条的索引值计算,使得频谱图呈现彩虹色的效果。
当用户点击"暂停"按钮时,音频暂停播放,并调用cancelAnimationFrame(animationId)来停止绘制频谱图。
请确保将audioElement.src中的路径替换为你要播放的实际音频文件的路径。
当然修改draw函数可以得到其他的音频图,比如波形图

具体的draw代码如下
这个函数主要用于绘制音频的时域波形图。它也使用了requestAnimationFrame()方法来请求下一帧动画,并将自身作为回调函数。
在函数内部,analyser.getByteTimeDomainData(dataArray)用于获取当前的音频时域数据,将数据存储在dataArray数组中。
然后,画布被清空,并将背景颜色设置为lime。
接下来,设置线条的宽度和颜色。
然后,开始绘制路径。
通过计算每个数据片段的宽度,以及根据时域数据计算每个点的纵坐标,确定波形图的绘制参数。
然后,根据波形点的位置,使用moveTo()方法将绘制路径移动到第一个点的位置,并使用lineTo()方法连接到下一个点的位置。这样就形成了一条完整的波形路径。
在遍历完所有的数据点后,使用lineTo()方法将最后一个点连接到画布的右侧中点,以形成闭合路径。
最后,使用stroke()方法绘制路径。
通过不断调用requestAnimationFrame()方法并在每一帧更新波形图,可以实现连续的动画效果。
使用js写一个音乐音谱图的更多相关文章
- 原生js写一个无缝轮播图插件(支持vue)
轮播图插件(Broadcast.js) 前言:写这个插件的原因 前段时间准备用vue加上网易云的nodejs接口,模拟网易云音乐移动端.因为想自己写一遍所有的代码以及加固自己的flex布局,所以没有使 ...
- 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
- JS写一个简单日历
JS写一个日历,配合jQuery操作DOM <!DOCTYPE html> <html> <head> <meta charset="UTF-8&q ...
- Vue折腾记 - (3)写一个不大靠谱的typeahead组件
Vue折腾记 - (3)写一个不大靠谱的typeahead组件 2017年07月20日 15:17:05 阅读数:691 前言 typeahead在网站中的应用很多..今天跟着我来写一个不大靠谱的ty ...
- 前端与编译原理——用JS写一个JS解释器
说起编译原理,印象往往只停留在本科时那些枯燥的课程和晦涩的概念.作为前端开发者,编译原理似乎离我们很远,对它的理解很可能仅仅局限于"抽象语法树(AST)".但这仅仅是个开头而已.编 ...
- 如何使用 js 写一个正常人看不懂的无聊代码
如何使用 js 写一个正常人看不懂的无聊代码 代码质量, 代码可读性, 代码可维护性, clean code WAT js WTF https://www.destroyallsoftware.com ...
- 用原生js写一个"多动症"的简历
用原生js写一个"多动症"的简历 预览地址源码地址 最近在知乎上看到@方应杭用vue写了一个会动的简历,觉得挺好玩的,研究一下其实现思路,决定试试用原生js来实现. 会动的简历实现 ...
- 【Part1】用JS写一个Blog(node + vue + mongoDB)
学习JS也有一段时间了,准备试着写一个博客项目,前后端分离开发,后端用node只提供数据接口,前端用vue-cli脚手架搭建,路由也由前端控制,数据异步交互用vue的一个插件vue-resourse来 ...
- [NodeJS]使用Node.js写一个简单的在线聊天室
声明:教程来自<Node即学即用>.源代码案例均出自此书.博文仅为个人学习笔记. 第一步:创建一个聊天server. 首先,我们先来写一个Server: var net = require ...
- 使用 Node.js 写一个代码生成器
背景 第一次接触代码生成器用的是动软代码生成器,数据库设计好之后,一键生成后端 curd代码.之后也用过 CodeSmith , T4.目前市面上也有很多优秀的代码生成器,而且大部分都提供可视化界面操 ...
随机推荐
- 2021-8-5 Mysql个人练习题
创建学校表格 CREATE TABLE `Student`( `s_id` VARCHAR(20), `s_name` VARCHAR(20) NOT NULL DEFAULT '', `s_birt ...
- HBase Compaction 原理与线上调优实践
作者:vivo 互联网存储技术团队- Hang Zhengbo 本文对 HBase Compaction 的原理.流程以及限流的策略进行了详细的介绍,列举了几个线上进行调优的案例,最后对 Compac ...
- 自用 .net C# CSV文件写入读取工具类
using System.Data; using System.IO; using System.Linq; using System.Text; using System.Text.RegularE ...
- rpm安装21c单实例数据库
linux 7.6 使用rpm安装21c单实例数据库 一.基础环境配置 1.1 关闭防火墙 systemctl stop firewalld systemctl disable firewalld s ...
- HTTPS 是这样握手的
HTTP协议默认是明文传输,存在一定的安全隐患,容易被中间人窃听和攻击,在 加密解决HTTP协议带来的安全问题 中提到使用哈希.对称加密.非对称加密等方式对数据加密,能解决数据安全的问题. 以上加密方 ...
- react中使用动画 react-transition-group
在React中通过react-transition-group使用过渡.动画,首先要有CSS3中的过渡和动画的相关知识储备,可以参考 过渡和2D变换.动画和3d变换. 我们自己通过css设置过渡.动画 ...
- Mysql高级8-触发器
一.触发器 触发器是与表有关的数据库对象,指在insert/update/delete之前或者之后,触发并执行触发器中定义的sql语句集合,触发器的这种特性可以协助应用在数据库端确保数据的完整性,日志 ...
- Unity UGUI的Button组件的介绍及使用
UGUI的Button(按钮)组件的介绍及使用 1. 什么是UGUI的Button组件? UGUI(Unity GUI)是Unity引擎中的一套用户界面系统,Button(按钮)是其中的一个常用组件. ...
- 《SQL与数据库基础》17. InnoDB引擎
目录 InnoDB引擎 逻辑存储结构 架构 内存结构 磁盘结构 后台线程 事务原理 事务基础 redo log undo log MVCC 基本概念 隐式字段 undo log版本链 readView ...
- 初识Redis与桌面客户端
Redis介绍 什么是Redis Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库. Redi ...