这个小东西是在去年八月份就完成的啦,但是由于自己一拖再拖没有来更新博客,直到今天心血来潮想来更新下博客。
今天就来记录下自己做完这个小小的迷你小项目—music-player。
哈哈,由于自己艺术细胞有限,再加上是个简洁控,自己粗略设计了一下,所以我的ui界面长这样—
界面分割:至上而下是歌名-歌手-音乐封面-播放时间-播放进度条-控制按钮
功能上实现:显示歌曲总时间,显示歌曲已播放时间,显示歌曲进度,拉拽歌曲进度,上一曲,暂停,播放,下一曲
未实现功能:歌曲列表展示,循环播放等等
html整体架构:
<section class="main">
<section class="info">
<h1></h1>
<h5></h5>
</section>
<section class="cd-ani">
<img src="images/singer.png" alt=""/>
</section>
<section class="progress">
<div class="pro-time clearfix">
<span id="had-time" class="fl">0:00</span>
<span id="all-time" class="fr">0:00</span>
</div>
<div class="total">
<div class="had-play"><div class="bar" id="drag"></div></div>
</div>
</section>
<section class="audio">
<audio controls="controls" id="music" src=""></audio>
</section>
<section class="operate clearfix">
<div id="last"><img src="images/last.png" alt=""/></div>
<div id="start"><img src="images/start.png" alt=""/></div>
<div id="next"><img src="images/next.png" alt=""/></div>
</section>
</section>
样式和图片什么的就不再详细多说,因为就是那些一般常用的东西。。。哈哈哈
歌曲信息是我之前从网易云音乐上面拿下来的一大串json数据,现在被我保存在本地里,防止网易云那边有什么变动之类的,对于跨域那些也没有多大问题。
把json数据都拿下来之后,就开始动工处理这些密密麻麻的数据啦~~兴奋。
js开始go~
首先我定义了一个对象(命名空间)以防变量污染 var music = {}
处理json:
ajax:function(){
$.ajax({
cache:false,
dataType:'json',
type:'post',
url:'../Common/json/musicJson.php',
data:{},
success:function(obj){
var dataArr = obj.result.tracks,
musicUrl = dataArr[curSong].mp3Url,
musicName = dataArr[curSong].name,
singer = dataArr[curSong].artists[0].name;
$('#music').attr('src',musicUrl);
$('.info h1').html(musicName);
$('.info h5').html(singer);
},
error:function(){
console.log('error')
}
});
}
英文命名很明显啦,就先把歌名,歌手,音乐链接都放上页面。(取第一首,即curSong=0)
由于音频不止一首,所以不要忘记很重要的一句代码:
var audio = $('#music').get(0)
播放音乐
start:function(){
audio.play();
$('.cd-ani img').addClass('rotate');
}
暂停音乐
pause:function(){
audio.pause();
$('.cd-ani img').removeClass('rotate');
}
其中$('.cd-ani img').removeClass('rotate')
是音乐封面旋转动画效果
播放下一首
next:function(){
curSong ++;
this.ajax();
}
时间显示
time : function(){
var allTime = audio.duration,
hadTime = audio.currentTime;
$('#had-time').html(cutTime(hadTime / 60) + ":" + cutTime(hadTime % 60));
$('#all-time').html(cutTime(allTime / 60) + ":" + cutTime(allTime % 60));
}
处理时间显示格式
超过60的时候往进一位数。
function cutTime(time){
var value = (time > 10 ? time + '' : '0' + time).substring(0, 2);
return isNaN(value) ? '00' : value;
}
进度条显示
获取音频的duration属性之后进行计算,将结果转化为进度条的长度(样式)
function progress(){
var cuT = audio.currentTime,
toT = audio.duration,
progress = (cuT/toT).toFixed(2)*375;
$('.had-play').width(progress);
}
拉拽进度条
最棘手的来了….对进度条的操作,手动拉拽进度条的部分
function addListenTouch() {
//var speed = $('.had-play');
var drag = document.getElementById("drag");
document.getElementById("drag").addEventListener("touchstart", touchStart, false);
document.getElementById("drag").addEventListener("touchmove", touchMove, false);
document.getElementById("drag").addEventListener("touchend", touchEnd, false);
}
function touchStart(e) {
e.preventDefault();
var touch = e.touches[0];
startX = touch.pageX;
}
function touchMove(e) { //滑动
e.preventDefault();
var touch = e.touches[0];
x = touch.pageX - startX; //滑动的距离
//drag.style.webkitTransform = 'translate(' + 0+ 'px, ' + y + 'px)';
var widthBar = aboveX + x;
if(widthBar<320){
drag.style.left = widthBar + "px";
$('.had-play').width(widthBar);
}//不让进度条超出页面
}
function touchEnd(e) { //手指离开屏幕
e.preventDefault();
aboveX = parseInt(drag.style.left);
var touch = e.touches[0];
var dragPaddingLeft = drag.style.left;
var change = dragPaddingLeft.replace("px", "");
numDragpaddingLeft = parseInt(change);
var currentTime = (numDragpaddingLeft / (window.innerWidth - 30)) * audio.duration;//30是拖动圆圈的长度,减掉是为了让歌曲结束的时候不会跑到window以外
audio.currentTime = currentTime;
console.log(currentTime);
music.time();
}
当我们手指在手机屏幕上滑动进度条的时候,可以分割成三个事件,分别是touchstart,touchmove,touchend,手指刚触碰到屏幕时候触法touchstart事件,调用函数touchstart()来记录此时手指距离进度条最左边的距离;滑动过程中出发touchmove事件,调用touchmove()函数,计算滑动距离,并且限制进度条拉伸超过最大范围;手指滑动停止时候触法touchend事件,调用touchend()函数计算最终长度并更改显示歌曲播放时间。
初始化
music.ajax();
addListenTouch();
audio.onloadedmetadata=function(){ music.time();}
总结
这次自己的小尝试,认识关于html5中audio元素的很多知识点,包括对audio元素的dom操作,和相关属性、方法的运用。过程中也出现很多问题,比如初始化时直接调用music.time()
会出错,上网查阅相关资料后才知道要audio.onloadedmetadata=function(){ music.time();}
这样调用才不会出错。并且,一开始那个进度条拉拽的对于自己来说其实是最难的,因为有时候使劲拉的话,进度条会空出一截,即断层了,这是个大大的bug,到现在还没有解决哈哈哈,现在还在思索中,有看出什么解决这个bug方法或者发现文中我的代码有误的欢迎前来指正哈哈~~~