本文主要介绍了原生JS实现音乐播放器的示例代码,分享给大家,具体如下:
效果图
音乐播放器
- 播放控制
- 播放进度条控制
- 歌词显示及高亮
- 播放模式设置
播放器属性归类
按照播放器的功能划分,对播放器的属性和DOM元素归类,实现同一功能的元素和属性保存在同一对象中,便于管理和操作
const control = { //存放播放器控制
play: document.querySelector('#myplay'),
...
index: 2,//当前播放歌曲序号
...
}
const audioFile = { //存放歌曲文件及相关信息
file: document.getElementsByTagName('audio')[0],
currentTime: 0,
duration: 0,
}
const lyric = { // 歌词显示栏配置
ele: null,
totalLyricRows: 0,
currentRows: 0,
rowsHeight: 0,
}
const modeControl = { //播放模式
mode: ['顺序', '随机', '单曲'],
index: 0
}
const songInfo = { // 存放歌曲信息的DOM容器
name: document.querySelector('.song-name'),
...
}
播放控制
功能:控制音乐的播放和暂停,上一首,下一首,播放完成及相应图标修改
audio所用API:audio.play() 和 audio.pause()和audio ended事件
// 音乐的播放和暂停,上一首,下一首控制
control.play.addEventListener('click',()=>{
control.isPlay = !control.isPlay;
playerHandle();
} );
control.prev.addEventListener('click', prevHandle);
control.next.addEventListener('click', nextHandle);
audioFile.file.addEventListener('ended', nextHandle);
function playerHandle() {
const play = control.play;
control.isPlay "htmlcode">
// 播放进度实时更新
audioFile.file.addEventListener('timeupdate', lyricAndProgressMove);
// 通过拖拽调整进度
control.progressDot.addEventListener('click', adjustProgressByDrag);
// 通过点击调整进度
control.progressWrap.addEventListener('click', adjustProgressByClick);
播放进度实时更新:通过修改相应DOM元素的位置或者宽度进行修改
function lyricAndProgressMove() {
const audio = audioFile.file;
const controlIndex = control.index;
// 歌曲信息初始化
const songLyricItem = document.getElementsByClassName('song-lyric-item');
if (songLyricItem.length == 0) return;
let currentTime = audioFile.currentTime = Math.round(audio.currentTime);
let duration = audioFile.duration = Math.round(audio.duration);
//进度条移动
const progressWrapWidth = control.progressWrap.offsetWidth;
const currentBarPOS = currentTime / duration * 100;
control.progressBar.style.width = `${currentBarPOS.toFixed(2)}%`;
const currentDotPOS = Math.round(currentTime / duration * progressWrapWidth);
control.progressDot.style.left = `${currentDotPOS}px`;
songInfo.currentTimeSpan.innerText = formatTime(currentTime);
}
拖拽调整进度:通过拖拽移动进度条,并且同步更新歌曲播放进度
function adjustProgressByDrag() {
const fragBox = control.progressDot;
const progressWrap = control.progressWrap
drag(fragBox, progressWrap)
}
function drag(fragBox, wrap) {
const wrapWidth = wrap.offsetWidth;
const wrapLeft = getOffsetLeft(wrap);
function dragMove(e) {
let disX = e.pageX - wrapLeft;
changeProgressBarPos(disX, wrapWidth)
}
fragBox.addEventListener('mousedown', () => { //拖拽操作
//点击放大方便操作
fragBox.style.width = `14px`;fragBox.style.height = `14px`;fragBox.style.top = `-7px`;
document.addEventListener('mousemove', dragMove);
document.addEventListener('mouseup', () => {
document.removeEventListener('mousemove', dragMove);
fragBox.style.width = `10px`;fragBox.style.height = `10px`;fragBox.style.top = `-4px`;
})
});
}
function changeProgressBarPos(disX, wrapWidth) { //进度条状态更新
const audio = audioFile.file
const duration = audioFile.duration
let dotPos
let barPos
if (disX < 0) {
dotPos = -4
barPos = 0
audio.currentTime = 0
} else if (disX > 0 && disX < wrapWidth) {
dotPos = disX
barPos = 100 * (disX / wrapWidth)
audio.currentTime = duration * (disX / wrapWidth)
} else {
dotPos = wrapWidth - 4
barPos = 100
audio.currentTime = duration
}
control.progressDot.style.left = `${dotPos}px`
control.progressBar.style.width = `${barPos}%`
}
点击进度条调整:通过点击进度条,并且同步更新歌曲播放进度
function adjustProgressByClick(e) {
const wrap = control.progressWrap;
const wrapWidth = wrap.offsetWidth;
const wrapLeft = getOffsetLeft(wrap);
const disX = e.pageX - wrapLeft;
changeProgressBarPos(disX, wrapWidth)
}
歌词显示及高亮
功能:根据播放进度,实时更新歌词显示,并高亮当前歌词(通过添加样式)
audio所用API:audio timeupdate事件,audio.currentTime
// 歌词显示实时更新
audioFile.file.addEventListener('timeupdate', lyricAndProgressMove);
function lyricAndProgressMove() {
const audio = audioFile.file;
const controlIndex = control.index;
const songLyricItem = document.getElementsByClassName('song-lyric-item');
if (songLyricItem.length == 0) return;
let currentTime = audioFile.currentTime = Math.round(audio.currentTime);
let duration = audioFile.duration = Math.round(audio.duration);
let totalLyricRows = lyric.totalLyricRows = songLyricItem.length;
let LyricEle = lyric.ele = songLyricItem[0];
let rowsHeight = lyric.rowsHeight = LyricEle && LyricEle.offsetHeight;
//歌词移动
lrcs[controlIndex].lyric.forEach((item, index) => {
if (currentTime === item.time) {
lyric.currentRows = index;
songLyricItem[index].classList.add('song-lyric-item-active');
index > 0 && songLyricItem[index - 1].classList.remove('song-lyric-item-active');
if (index > 5 && index < totalLyricRows - 5) {
songInfo.lyricWrap.scrollTo(0, `${rowsHeight * (index - 5)}`)
}
}
})
}
播放模式设置
功能:点击跳转播放模式,并修改相应图标
audio所用API:无
// 播放模式设置
control.mode.addEventListener('click', changePlayMode);
function changePlayMode() {
modeControl.index = ++modeControl.index % 3;
const mode = control.mode;
modeControl.index === 0 "class", "playerIcon songCycleOrder") :
modeControl.index === 1 "class", "playerIcon songCycleRandom ") :
mode.setAttribute("class", "playerIcon songCycleOnly")
}
项目预览
代码地址:https://github.com/hcm083214/audio-player
JS,音乐播放器
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]
