觀察須製作的功能 成品
播放器API的樣式
<audio>: The Embed Audio element
播放時,左方的圓型圖示會旋轉。
先於css檔案製作符合動畫的class
在js時,依照符合的情況加入該class
播放時,上方會跳出播放歌曲的名稱。
先於css檔案製作符合動畫的class,設定opacity
1或0,translateY
位置的移動
在js時,依照符合的情況加入該class
左右按鍵可以更換曲目,同時圖片會更換
設定陣列,使歌曲與圖片相符
並讓前後的跳轉鍵,依照順序或條件來變化
html部分 跳轉按鍵
1 2 3 4 5 6 7 8 9 10 11 12 13 <div class ="nav" > <button id ="prev" class ="action-btn" > <i class ="fas fa-backward" > </i > </button > <button id ="play" class ="action-btn action-btn-big" > <i class ="fas fa-play" > </i > </button > <button id ="next" class ="action-btn" > <i class ="fas fa-forward" > </i > </button > </div >
css部分 背景顏色 linear-gradient()
1 2 3 4 background-image :linear-gradient (0deg ,rgb (247 , 247 , 247 ,1 ) 23.8% , rgba (252 ,221 ,221 ,1 ) 92% );
圖片圓形以及旋轉 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 .img-container { position : relative; width : 110px ; } .img-container img { border-radius : 50% ; object-fit : cover; height : 110px ; width : inherit; position :absolute; bottom : 0 ; left : 0 ; animation : rotate 3s linear infinite; animation-play-state : paused; } .music-container .play .img-container img { animation-play-state :running; } @keyframes rotate{ from { transform : rotate (0deg ); } to { transform : rotate (360deg ); } }
1 2 3 4 5 6 7 8 9 10 11 .img-container ::after { content : '' ; border-radius : 50% ; background-color : #fff ; position : absolute; left : 50% ; bottom : 100% ; width : 25px ; height : 25px ; transform : translate (-50% ,50% ); }
播放進度條的製作
標題1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .music-info { background-color : rgba (255 ,255 ,255 ,.5 ); border-radius :15px 15px 0 0 ; position : absolute; top : 0 ; left : 20px ; opacity : 0 ; transform : translateY (0% ); transition : transform 0.3s ease-in,opacity 0.3s ease-in; z-index : 0 ; } .music-container .play .music-info { opacity : 1 ; transform : translateY (-100% ); }
將曲目標題設置背景、圓角
利用 transfor、opacity來呈現位置的變化
1 2 3 width : calc (100% - 40px ); padding : 10px 10px 10px 150px ;
calc()
calc() 的運算式一樣是按照先乘除後加減進行計算 width: calc(100% - 40px); /* 意思是 100% 的寬度 - 去 40px */CSS: calc() 數值運算
1 2 3 4 .music-info h4 {margin : 0 ;}
2.進度條(progress)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 .progress-container { background-color : #fff ; border-radius : 5px ; height : 4px ; width : 100% ; margin : 10px 0 ; cursor : pointer; } .progress { background-color : #fe8daa ; border-radius : 5px ; height : 4px ; width : 0% ; transition : width .1s linear ; }
js部分 1.音樂播放鍵(播放與停止)
分別有兩個函式:playMusic()
、pauseMusic()
在css設定.play
的css,並於js綁定事件,加入css的效果(使圖片如同轉盤,會旋轉)
在icon的部分:在播放時:為暫停鍵圖示;在暫停時:為播放鍵的圖示
透過play()、pause(),讓音源播放與暫停
play()
、pause()
因為play()、pause()是DOM元素,不是jQuery的function,而要用jQuery取得DOM元素$('#audio').get(0).play()
=>$('#audio')[0].play()
$('#audio').get(0).pause()
=>$('#audio')[0].pause()
參考資料:How do I pull a native DOM element from a jQuery object? Play/pause HTML 5 video using JQuery
1 2 3 4 5 6 7 8 9 function playMusic ( ) { $('.music-container' ).addClass ('play' ); $('#play' ).find ('i' ).removeClass ('fa-play' ); $('#play' ).find ('i' ).addClass ('fa-pause' ); $('#audio' ).get (0 ).play (); };
1 2 3 4 5 6 7 function pauseMusic ( ) { $('.music-container' ).removeClass ('play' ); $('#play' ).find ('i' ).addClass ('fa-play' ); $('#play' ).find ('i' ).removeClass ('fa-pause' ); $('#audio' ).get (0 ).pause (); }
綁定事件: 如果音樂是播放狀態的話,就執行pauseMusic()
,反之,音樂不處於波方時,執行playMusic()
1 2 3 4 5 6 7 8 9 10 $('#play' ).click (function (e ) { var hasPlay = $('#music-container' ).hasClass ('play' ); if (hasPlay) { pauseMusic (); } else { playMusic (); } });
2.載入音樂
將歌曲名稱建立陣列,並將此回傳到建立的函式中
設定預設的索引let songIndex = 1
使用 attr( 屬性名, 屬性值 ),獲取屬性的值,在這部分,透過歌曲名稱來取得歌曲與照片
1 2 3 4 5 6 7 8 9 10 11 12 13 var songs_name = ['hey' , 'summer' , 'ukulele' ];let songIndex = 1 ;function loadSongs (song ) { $('#title' ).text (song); $('#audio' ).attr ('src' , `music/${song} .mp3` ); $('#cover' ).attr ('src' , `img/${song} .jpg` ); } loadSongs (songs_name[songIndex]);
綁定於下一首、前一首的圖示被點擊時 1 2 3 $('#next' ).click (nextSong) $('#prev' ).click (function ( ) { prevSong (); });
參考資料:jquery prop和attr的區別 jQuery .attr() vs .prop()
3.左右鍵的跳轉
下一首歌曲,與跳至前一首歌曲,兩個函式的撰寫有異曲同工之妙,只有在設條條件上的差異。
nextSong()
:設定條件為歌曲索引songIndex
比 歌曲陣列長度-1songs_name.length - 1
還要小,我們就要將索引+1。
例如這裏預設的索引為1,所以在點擊當下,判斷<songs_name.length - 1
,所以需加1,索引變成2,跳至下一首 ‘ukulele’
prevSong():設定條件為歌曲索引songIndex
比0大,就要索引-1,跳轉至上一首歌曲。若沒符合的話,索引就等於songs_name.length - 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function nextSong ( ) { if (songIndex < songs_name.length - 1 ) { songIndex += 1 ; } else { songIndex = 0 }; loadSongs (songs_name[songIndex]); playMusic (); } function prevSong ( ) { if (songIndex > 0 ) { songIndex -= 1 ; } else { songIndex = songs_name.length - 1 ; }; loadSongs (songs_name[songIndex]); playMusic (); }
參考資料:Create a Music Player using JavaScript
4.點擊進度條,可以跳轉音樂位置 (1).顯示粉色進度條
duration:音源的時間(一樣是使用get方式取得)
currentTime:音樂播放的當前位置(以秒計)
progressBar:進度條
計算百分比:(currentTime / duration) * 100
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function handleProgress ( ) { var duration = $('#audio' ).get (0 ).duration ; var currentTime = $('#audio' )[0 ].currentTime ; const progressBar = $('#progress' ); const progressPercent = (currentTime / duration) * 100 ; progressBar.css ('width' , `${progressPercent} %` ); };
(2).點擊進度條,會跳轉到該位置播放
width:獲取該進度條容器的寬度
抓取點擊位置:
e.pageX:取得滑鼠在頁面裡的位置
elm.offset().left:絕對座標X軸
將(點擊位置除以進度條的總長)乘以 音樂的時間長度,就可以取得點擊的時間位置theTime = ((xPos / width))* duration;
最後現在時間設為,計算好的點擊時間
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $('#progress-container' ).click (function (e ) { const width = $('#progress-container' ).width (); var elm = $(this ); var xPos = e.pageX - elm.offset ().left ; var duration = $('#audio' )[0 ].duration ; var theTime = ((xPos / width)) * duration; $('#audio' )[0 ].currentTime = theTime; });
執行過程,利用console來查看
1 2 3 console .log (e.pageX );console .log (elm.offset ().left );console .log (xPos)
參考資料:取得滑鼠位置、元素位置與區塊內的相對位置
5.歌曲播完後,換下一首 1 $('#audio' ).on ('ended' ,nextSong);
參考資料:audio auto play next song when previous is finished
6.增加隨機的變換背景色彩
色彩為0-256;而因為想取的較亮的色系,所以取64-256
Math.random()
會回傳一個偽隨機小數 (pseudo-random) 介於0到1之間(包含 0,不包含1)
Math.floor()
會將所有的小數無條件捨去到比自身小的最大整數
Math.floor(Math.random() * 255) + 64
就會取得64 to 256
宣告變數bgColor
為rdba(red,green,blue,a)
最後將此函式,放入loadSongs()
函式當中,每次播放、跳轉歌曲,同時背景顏色也會改變
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function random_bg_color ( ) { let red = Math .floor (Math .random () * 255 ) + 64 ; let green = Math .floor (Math .random () * 255 ) + 64 ; let blue = Math .floor (Math .random () * 255 ) + 64 ; let a = 0.5 let bgColor = "rgba(" + red + ", " + green + ", " + blue + ", " + a + ")" ; var bg = $(document .body ).css ('background' , `${bgColor} ` ); bg = bgColor; console .log (bg) }
參考資料:Create a Music Player using JavaScript Won’t Math.floor(Math.random() * 255) generate uneven probabilities?
[筆記][JavaScript]用Math.random()取得亂數的技巧