实现进度条
使用一个 <div>
设置样式来作为进度条的导轨;在其内部使用两个 <div>
分别设置样式来作为当前播放时间所占的进度条和其头部的拖拽点。
通过音乐媒体文件的 currentTime
和 duration
来计算出当前时间占音乐总时间的百分比(currentTime / duration);结合导轨的宽度(Element.clientWidth)即可算出当前播放时间所占进度条的宽度(X轴)和其头部拖拽点的位置(X轴)。将上述操作设置在定时器中来定时执行以实现播放时进度条的增长。
当有点击时间使播放进度发生改变时,通过点击事件中鼠标的与浏览器左边界的距离 e.clientX
和 进度条导轨与浏览器左边界的距离 Element.getBoundingClientRect().left
来计算出点击位置在进度条上的距离;根据此来设置当前播放时间、所占进度条的宽度(X轴)和其头部拖拽点的位置(X轴)。
通过 mousedown
、 mousemove
和 mouseup
事件来响应鼠标按键点击,鼠标移动(拖拽),鼠标按键抬起的动作;在 mousemove
事件中通过移动事件中鼠标的与浏览器左边界的距离 e.clientX
和 进度条导轨与浏览器左边界的距离 Element.getBoundingClientRect().left
来计算出当前移动到的位置;根据位置比例计算出对应的播放时间,在 mouseup
事件中将该时间设置为音乐媒体文件的 currentTime
来实现播放进度的跳转。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>MusicControl</title>
<style>
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
.control-button {
margin-top: 10px;
margin-left: 20px;
}
.control-button::after {
content: '';
display: block;
clear: both;
}
.play-control-button {
width: 64px;
height: 64px;
background-image: url(icons.png);
float: left;
margin-right: 10px;
cursor: pointer;
}
.prev {
background-position: 0 0;
}
.next {
background-position: 0 -64px;
}
.play {
background-position: 0 -192px;
}
.pause {
background-position: 0 -128px;
}
.control-bar {
margin-top: 20px;
margin-left: 20px;
}
.control-bar::after {
content: '';
display: block;
clear: both;
}
.controlTime {
float: left;
color: #ccc;
}
.play-control-progress {
position: relative;
margin-left: 8px;
margin-right: 8px;
margin-top: 8px;
float: left;
display: block;
width: 300px;
height: 5px;
background-color: #ccc;
}
.playing-progress {
position: absolute;
display: block;
height: 100%;
width: 0%;
background-color: #2f9842;
}
.playing-bar {
position: absolute;
margin-top: -1.5px;
margin-left: -4px;
width: 8px;
height: 8px;
background-color: #2f9842;
border: 0.5px solid #000;
border-radius: 50%
}
</style>
</head>
<body>
<audio id="music" src="demo.mp3"></audio>
<div class="control-button">
<div class="play-control-button prev" id="controlOne"></div>
<div class="play-control-button play" id="controlTwo"></div>
<div class="play-control-button next" id="controlThree"></div>
</div>
<div class="control-bar">
<span class="controlTime" id="nowTime">00:00</span>
<div class="play-control-progress" id="controlProgress">
<div class="playing-progress" id="playingProgress"></div>
<div class="playing-bar" id="playingBar"></div>
</div>
<span class="controlTime" id="endTime">00:00</span>
</div>
<script>
window.onload = function() {
let music = document.getElementById('music');
let controlOne = document.getElementById('controlOne');
let controlTwo = document.getElementById('controlTwo');
let controlThree = document.getElementById('controlThree');
let controlProgress = document.getElementById('controlProgress');
let playingProgress = document.getElementById('playingProgress');
let playingBar = document.getElementById('playingBar');
let nowTime = document.getElementById('nowTime');
let endTime = document.getElementById('endTime');
let drag = 0;
let flag = 0;
nowTime.innerText = "00:00";
function getMin(min) {
let res = parseInt(min / 60);
if(res < 10) {
return '0' + res;
} else {
return res + '';
}
}
function getSec(min) {
let res = parseInt(min % 60);
if(res < 10) {
return '0' + res;
} else {
return res + '';
}
}
endTime.innerText = getMin(music.duration) + ":" + getSec(music.duration);
let timer = '';
let stop = '';
controlTwo.addEventListener('click', () => {
console.log("Click");
if(controlTwo.className == "play-control-button play") {
controlTwo.className = "play-control-button pause"
music.play();
timer = setInterval(() => {
let progressLen = music.currentTime / music.duration * controlProgress.clientWidth;
nowTime.innerText = getMin(music.currentTime) + ":" + getSec(music.currentTime);
playingProgress.style.width = progressLen + 'px';
playingBar.style.marginLeft = progressLen - 4 + 'px';
},1000);
} else if (controlTwo.className == "play-control-button pause") {
controlTwo.className = "play-control-button play";
music.pause();
clearInterval(timer);
}
})
controlProgress.addEventListener('click', (e) => {
let rate = ((e.clientX - controlProgress.getBoundingClientRect().left) / controlProgress.clientWidth);
let progressLen = e.clientX - controlProgress.getBoundingClientRect().left;
playingProgress.style.width = progressLen + 'px';
playingBar.style.marginLeft = progressLen - 4 + 'px';
let theTime = parseInt(rate * (music.duration))
music.currentTime = theTime;
nowTime.innerText = getMin(theTime) + ":" + getSec(theTime);
})
let dragTime = 0;
playingBar.addEventListener('mousedown', () => {
console.log('mousedown');
drag = 1;
flag = 1;
clearInterval(timer);
});
document.addEventListener('mouseup', () => {
console.log('mouseup');
drag = 0;
if(flag == 1) {
music.currentTime = dragTime;
timer = setInterval(() => {
let progressLen = music.currentTime / music.duration * controlProgress.clientWidth;
nowTime.innerText = getMin(music.currentTime) + ":" + getSec(music.currentTime);
playingProgress.style.width = progressLen + 'px';
playingBar.style.marginLeft = progressLen - 4 + 'px';
},1000);
}
flag = 0;
});
controlProgress.addEventListener('mousemove', (e) => {
if(drag == 1) {
console.log('mousemove');
let progressLen = e.clientX - controlProgress.getBoundingClientRect().left;
let rate = (progressLen / controlProgress.clientWidth);
playingProgress.style.width = progressLen + 'px';
playingBar.style.marginLeft = progressLen - 4 + 'px';
let theTime = parseInt(rate * (music.duration));
nowTime.innerText = getMin(theTime) + ":" + getSec(theTime);
dragTime = theTime;
}
})
}
</script>
</body>
</html>
对样式进行细微的调整,如对 playingBar
的 margin-left
设置少4个像素(其宽度的一半)使其中心对应鼠标点击或拖拽时的目标点。
网友评论