网站播放音乐特效
方案一:频谱可视化背景(推荐)
这种效果是最常见的,也是最能体现“炫酷”感的。我们需要用到 Web Audio API 和 Canvas。
- HTML 结构 (无需大改动):
<div class="mt-3 bg-white pt-2 pl-3 card" style="margin-top: 1px; border: 1px solid; padding: 2em; overflow: hidden; position: relative;">
<canvas id="audioVisualizer" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 0;"></canvas>
<div class="viny" style="text-align: center; position: relative; z-index: 1;">
<dl>
<dd id="songTitle" style="font-size: 18px; margin-top: 20px;">爱一点</dd>
<dd id="songArtist" style="color: #888;">歌手:莫艳琳</dd>
<dd id="songAlbum" style="color: #888;">专辑:宅情歌</dd>
<dd style="margin-top: 20px;">
<audio id="musicPlayer" controls style="width: 100%;" data-src="{% static 'music/aiyidian.mp3' %}">
Your browser does not support the audio element.
</audio>
<!-- 调整下一曲按钮样式,使其不那么显眼 -->
<button id="playNextBtn" class="plyr__controls__item plyr__controls__item--custom" aria-label="播放" type="button" style="background-color: #f2f2f2; color: #666; border: 1px solid #ccc; border-radius: 3px; padding: 5px 10px;">
<i class="fas fa-play"></i>
</button>
</dd>
</dl>
</div>
</div>
- 关键点:在原来的
.card
容器内,添加一个<canvas>
元素,并将其position
设为absolute
,使其覆盖整个容器作为背景。 - 同时,给原有的
.viny
内容设置position: relative; z-index: 1;
确保它显示在 Canvas 之上。
- JavaScript 代码 (核心):
<script>
document.addEventListener('DOMContentLoaded', () => {
const player = document.getElementById('musicPlayer');
const playNextBtn = document.getElementById('playNextBtn');
const songTitle = document.getElementById('songTitle');
const songArtist = document.getElementById('songArtist');
const songAlbum = document.getElementById('songAlbum');
const canvas = document.getElementById('audioVisualizer');
const ctx = canvas.getContext('2d');
let audioContext;
let analyser;
let source;
let bufferLength;
let dataArray;
// 歌曲列表
const songs = [
{
title: '爱一点',
artist: '莫艳琳',
album: '宅情歌',
src: '{% static "music/aiyidian.mp3" %}'
},
{
title: '我很快乐',
artist: '刘惜君',
album: '《我很快乐》',
src: '{% static "music/我很快乐.mp3" %}'
},
{
title: '晚安大小姐',
artist: 'ASMRZ',
album: '잘자요 아가씨',
src: '{% static "music/晚安大小姐.m4a" %}'
}
// 添加更多歌曲...
];
// 当前播放歌曲索引
let currentSongIndex = 0;
// 更新歌曲信息
function updateSongInfo() {
songTitle.textContent = songs[currentSongIndex].title;
songArtist.textContent = '歌手:' + songs[currentSongIndex].artist;
songAlbum.textContent = '专辑:' + songs[currentSongIndex].album;
}
// 播放状态标志
let isPlaying = false;
// 初始化音频上下文和分析器
function initAudio() {
if (!audioContext) {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
analyser = audioContext.createAnalyser();
analyser.fftSize = 2048; // 调整精度
bufferLength = analyser.frequencyBinCount;
dataArray = new Uint8Array(bufferLength);
source = audioContext.createMediaElementSource(player);
source.connect(analyser);
analyser.connect(audioContext.destination);
}
}
function setCanvasSize(){
canvas.width = canvas.offsetWidth; // 使用 offsetWidth 和 offsetHeight
canvas.height = canvas.offsetHeight;
}
// 绘制频谱
function drawSpectrum() {
requestAnimationFrame(drawSpectrum);
analyser.getByteFrequencyData(dataArray);
ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除画布
const barWidth = (canvas.width / bufferLength) * 2.5;
let barHeight;
let x = 0;
for (let i = 0; i < bufferLength; i++) {
barHeight = dataArray[i] * (canvas.height / 255); // 根据音量调整高度
// 设置颜色渐变
const r = barHeight + (25 * (i / bufferLength));
const g = 250 * (i / bufferLength);
const b = 50;
ctx.fillStyle = `rgb(${r}, ${g}, ${b})`;
ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
}
// 添加播放/下一曲按钮的点击事件
playNextBtn.addEventListener('click', () => {
if (!audioContext) {
initAudio(); // 首次点击时初始化
}
if (!isPlaying) {
// 如果未播放,则播放当前歌曲
player.src = songs[currentSongIndex].src;
player.load();
player.play();
isPlaying = true;
playNextBtn.innerHTML = '<i class="fas fa-forward"></i>'; // 播放时显示下一曲图标
} else {
// 如果已经在播放,则切换到下一首歌曲
currentSongIndex = (currentSongIndex + 1) % songs.length;
player.src = songs[currentSongIndex].src;
player.load();
player.play();
updateSongInfo();
}
setCanvasSize()
});
// 添加播放事件监听器
player.addEventListener('play', () => {
isPlaying = true;
playNextBtn.innerHTML = '<i class="fas fa-forward"></i>'; // 播放时显示下一曲图标
if (!audioContext) { //确保音频初始化
initAudio();
}
drawSpectrum(); // 开始绘制频谱
setCanvasSize()
});
// 添加暂停事件监听器
player.addEventListener('pause', () => {
isPlaying = false;
playNextBtn.innerHTML = '<i class="fas fa-play"></i>'; // 暂停时显示播放图标
});
// 初始化第一首歌曲信息
updateSongInfo();
setCanvasSize()
window.addEventListener('resize',setCanvasSize)
});
</script>
initAudio()
: 创建AudioContext
、AnalyserNode
,并将音频源连接到分析器,再连接到输出。drawSpectrum()
: 使用requestAnimationFrame
循环绘制。
*analyser.getByteFrequencyData(dataArray)
: 获取当前音频的频域数据。
* 在循环中,根据dataArray
中的值绘制不同高度、颜色的矩形,形成频谱效果。setCanvasSize()
:设置canvas铺满容器
方案二:粒子背景
这种效果会更具动感,我们可以使用一些现成的粒子库,如 particles.js
或 tsParticles
,也可以自己用 Canvas 手写。
- 引入粒子库 (以 tsParticles 为例):
<script src="https://cdn.jsdelivr.net/npm/tsparticles-engine"></script>
<script src="https://cdn.jsdelivr.net/npm/tsparticles"></script>
<!--如果需要特定的形状或交互,还需要引入对应的 preset-->
<script src="https://cdn.jsdelivr.net/npm/tsparticles-preset-fireworks@2/tsparticles-preset-fireworks.min.js"></script>
- HTML 结构 (类似于方案一):
<div class="mt-3 bg-white pt-2 pl-3 card" style="margin-top: 1px; border: 1px solid; padding: 2em; overflow: hidden; position: relative;">
<div id="tsparticles" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 0;"></div>
<div class="viny" style="text-align: center; position: relative; z-index: 1;">
<!--...其余部分相同...-->
</div>
- 初始化 tsParticles:
<script>
// ... (之前的歌曲播放逻辑) ...
tsParticles.load("tsparticles", {
preset: "fireworks", // 使用 fireworks 预设,可以换成其他的
fullScreen:{
enable:false, //避免遮挡页面其他部分
}
});
</script>
* tsParticles的配置项有很多,可以去官网查看文档:[https://particles.js.org/docs/](https://particles.js.org/docs/)
方案三:动态渐变背景
这是一种相对简单但也很美观的效果。
- CSS:
.card { /* 你的 .card 样式 */
/* 添加以下内容 */
background: linear-gradient(to right, #ff00cc, #333399); /* 初始渐变 */
animation: gradientAnimation 10s ease infinite; /* 添加动画 */
}
@keyframes gradientAnimation {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
linear-gradient
: 设置一个初始的渐变背景。animation
: 应用一个名为gradientAnimation
的动画。@keyframes gradientAnimation
: 定义动画的关键帧,这里让渐变背景的位置循环变化。
- JavaScript (可选):
如果要让背景渐变与音乐节奏同步,可以使用 Web Audio API 获取音频的响度或频率数据,然后用 JavaScript 动态修改 CSS 变量或直接修改background
属性。 但这实现起来会比较复杂,如果你只是需要一个动态的渐变背景,CSS 方案就足够了。
注意事项:
- 性能: 频谱可视化和粒子效果可能会对性能有一定影响,尤其是在低端设备上。如果出现卡顿,可以尝试降低频谱的精度 (
analyser.fftSize
) 或减少粒子的数量。 - 兼容性: Web Audio API 的兼容性很好,但如果需要支持非常老的浏览器,可能需要做一些兼容处理。
- 音频跨域: 如果你的音频文件和网页不在同一个域下,可能会遇到跨域问题,导致无法分析音频数据。你需要确保音频文件设置了正确的 CORS 头。
本文作者: 永生
本文链接: https://yys.zone/detail/?id=381
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
发表评论
评论列表 (0 条评论)
暂无评论,快来抢沙发吧!