今天我们看的是一个使用纯HTML+CSS+JS实现音乐播放器的例子,效果还是很赞的: codePen地址
HTML部分
首先我们要思考一下,一个播放器主要包含哪些元素。首先要有播放的进度信息,还有播放/暂停或者上一首下一首等必要的按钮,同时还要显示一些当前播放的音乐名称等信息。播放多首歌曲时,要显示播放列表。。。因此,从语义上可以构造出基本的HTML结构:
// 背景区块,用于显示当前播放音乐的图片 <div class='background' id='background'></div>// 播放器区块 <div id='player'><audio id='mytrack' src=''></audio>//顶部区域,只显示一幅画<div id='artwork'></div>// 播放列表<div id='tracks'><div trackartist='Tobu & Syndec' trackname='Dusk' trackartwork='01.jpg'></div><div trackartist='Disfigure' trackname='Blank' trackartwork='02.jpg'></div><div trackartist='Alan Walker' trackname='Fade' trackartwork='03.jpg'></div></div>//播放器的UI部分<div id='ui'>//播放器已播放时间和总的时间<div id="time"><span id='elapsedtime'>00:00</span><span id='totaltime'>00:00</span></div>//进度条<div id='progressbar'><div><span id='pointer'></span></div></div>// 播放器控件<div id='controls'><button id='prev' class='control'></button><button id='play' class='control'></button><button id='stop' class='control'></button><button id='next' class='control'></button></div></div> </div>
CSS部分
接下来看css部分。首先将player区块进行了居中,并添加了背景和阴影:
#playerwidth: 300pxposition: absoluteleft: 50%top: 50%box-shadow: 0px 5px 10px #000background-color: $color4transform: translate(-50%, -50%)-o-transform: translate(-50%, -50%)-moz-transform: translate(-50%, -50%)-webkit-transform: translate(-50%, -50%)
对于顶部的图像区块,设置充满宽度,并设置图像水平和垂直方向都居中,当图像切换时,增加了1s的过渡效果。
#artworkwidth: 100%height: 0padding-bottom: 100%display: blockposition: relativeoverflow: hiddenbackground-image: url("../artworks/01.jpg")background-repeat: no-repeatbackground-size: coverbackground-position: center centertransition: background 1s ease 0s-o-transition: background 1s ease 0s-moz-transition: background 1s ease 0s-webkit-transition: background 1s ease 0s
这里将height设置为0,然后padding-bottom设置为100%(相对与父元素的宽度),由于它的宽和父元素的宽相同,结果就是将它的宽和高设成相同,即300px * 300px。
播放列表区块首先是一个列表,因此我们直观地想到了用ul/li来实现,但是这里用的是将父元素设置display:table,然后每项的图片和名字设置为display: table-cell的形式:
#trackswidth: 100%display: blockoverflow: hiddenbackground-color: #fffdivwidth: 100%display: tablebackground-color: #ffftransition: all 0.5s ease 0s-o-transition: all 0.5s ease 0s-moz-transition: all 0.5s ease 0s-webkit-transition: all 0.5s ease 0scursor: pointerspanmargin-right: 10pxdisplay: table-cellpadding: 0px 10pxheight: 50pxline-height: 50pxfont-size: 1.2emcolor: #aaaartworktext-align: centerdisplay: table-cellwidth: 50pxbackground-repeat: no-repeatbackground-size: coverbackground-position: center center
UI区块是重点,主要包括时间、进度条和控件三个部分。时间按理来说在布局上比较简单,但这里它又用到了我们想不到的display:list-item来实现(相当于ul,其实我觉得这里没有写这些),然后又用了css3中的first-of-type伪类用来匹配该类型的第一个元素等。
进度条主要是通过将div的宽度逐渐增大并进行过渡。还有一个pointer,通过将它的背景设置为发亮,表明当前播放的位置。
#progressbarwidth: 100%display: blockoverflow: hiddenheight: $progressHeightbackground-color: $color4 - 10cursor: pointerdivwidth: 0%height: $progressHeightdisplay: blockfloat: leftbackground-color: $color3 - 40transition: width 0.1s ease 0s-o-transition: width 0.1s ease 0s-moz-transition: width 0.1s ease 0s-webkit-transition: width 0.1s ease 0s#pointerwidth: 4pxheight: $progressHeightdisplay: blockfloat: rightbackground-color: $color3transform: translate(100%,0)
最后是控件部分。每个控件的宽度设为25%向左浮动,并再次用到了display:list-item
.controlwidth: 25%height: 50pxfloat: leftdisplay: list-itemlist-style: nonebackground-repeat: no-repeatbackground-color: transparentbackground-size: 20pxbackground-position: center centertransition: background 0.1s ease 0s-o-transition: background 0.1s ease 0s-moz-transition: background 0.1s ease 0s-webkit-transition: background 0.1s ease 0s&:hovercursor: pointer
JS部分
最后我们要看的是交互部分。交互主要包括:
- 换歌:在列表中高亮当前播放的歌曲,切换背景图片,播放
- 播放:播放声音,调整进度条,显示正确的按钮背景
- 上一条/下一条:=换歌,但还要考虑到第一首和最后一首的特殊情况
- 暂停/恢复:暂停/恢复音频的播放,显示正确的按钮背景
- 进度条点击:更新当前播放的时间点
总之,包含的有:currentAudio, isPlaying, audioPosition这几个状态信息。
比如点击了下一首,它会做这么几个交互上的改变:
- 按钮背景有一个状态按下的效果
- 停止当前歌曲的播放
- 重置进度条的位置
- 歌曲列表当前项显示有更新
- 顶部的封面有更新
- 如果当前isPlaying为true,则播放歌曲,更新进度条
// 1if(this.classList[0] !== "shadow"){for(var x = 0; x < audioControls.children.length; x++){audioControls.children[x].classList.remove("shadow");}this.classList.add("shadow");}// 2audio.currentTime = 0;clearInterval(timer);// 3 updateProgressBarPosition()// 4 updateActiveTrack(currentTrack);// 5 changeBackgroundImage(artwork, artworkSrc);// 6 audio.play();audioState = "play";changeBackgroundImage(play, iconsFolder + "pause.png");// Update the timetimer = setInterval(function(){updateTime();},100);