這個小東西是在去年八月份就完成的啦,但是由於自己一拖再拖沒有來更新博客,直到今天心血來潮想來更新下博客。
今天就來記錄下自己做完這個小小的迷你小項目—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方法或者發現文中我的代碼有誤的歡迎前來指正哈哈~~~