# Music Player 實作 ###### tags: `實作` `CSS` `javascript` [實作頁面連結](https://allenw0815.github.io/mission/mission_26/index.html) ![](https://i.imgur.com/FKmTHXY.png) ### Flowchart 1. 寫 HTML 結構 2. 寫 CSS,這實作比較複雜,應會用到偽元素以及 animate 3. 透過 JS 去讓 audio 播放以及暫停 4. 播放以及暫停時分別需要做哪些事情? 5. 讓進度條樣式對應到撥放的時間點上 > JS 流程 1.先把所需的 DOM 取好,用陣列存放歌曲名稱,畫面載入時依照陣列索引的名稱設定是哪首歌 ```javascript= const songs = ['Lost_in_paradise','Desperado','Wild_side','山雀','Yuve_Yuve_Yu'] let songIndex = 1 function loadingSong (song) { musicName.innerText = song.replaceAll('_',' ') //顯示歌名 替換掉不要的符號 audio.src = `music/${song}.mp3` //找對應音源 img.src = `img/${song}.png` //找對應圖片 } loadingSong(songs[songIndex]) ``` 2.點擊播放鍵時,判斷是否正在撥放分別去做暫停及播放兩個相反的 function ```javascript= const playingMode = () =>{ audio.play() // 音源播放 musicContainer.classList.add('play') // 替元素添加 class 來觸發 animate playBtn.querySelector('i').classList.remove('fa-play') // 移除當前圖示 playBtn.querySelector('i').classList.add('fa-pause') // 更新圖示 } function musicPlay() { const isPlaying = musicContainer.classList.contains('play') // 回傳 Boolean isPlaying ? pauseMode() : playingMode() } playBtn.addEventListener('click',musicPlay) ``` 3.前後鍵點擊 ```javascript= function musicNext() { songIndex < songs.length -1 ? songIndex++ : songIndex // 限制在最後一首 loadingSong(songs[songIndex]) // 更新歌曲 playingMode() // 播放 } nextBtn.addEventListener('click',musicNext) ``` 4.監聽歌曲長度以及當前歌曲時間搭配 CSS 實現進度條動畫及點擊跳轉 ```javascript= function updateProgress(e) { // 這邊為解構賦值 const {duration,currentTime} = e.srcElement // 取得總長跟播放到的長度 const progressPercent = (currentTime / duration) * 100 // 取得百分比的數字 progress.style.width = `${progressPercent}%` // 讓有顏色的進度條根據進度顯示 } audio.addEventListener('timeupdate',updateProgress) // 音源播放時持續觸發 // 正確說法是 currentTime 變更時觸發,感覺很耗能應該可以壓低頻率 function setProgress(e) { const width = this.clientWidth // div的長度 const x = e.offsetX // 點擊位置的長度 const duration = audio.duration audio.currentTime = ( x / width ) * duration // 代表點的位置是總長的幾分之幾再*總長就會得出相對應的當前播放時間然後更新currentTime } progressArea.addEventListener('click',setProgress) ``` 5.歌曲結束後換下一首,就好比結束後觸發點擊下一首按鍵一樣 ```javascript= audio.addEventListener('ended',musicNext) ``` ### 紀錄 * currentTime 播放時不停變更 ![](https://i.imgur.com/syuAd08.png) * 動畫可以使用多個效果 ```css= @keyframes rotate { 0%{ transform: rotate(0deg) scale(1); } 50%{ transform: rotate(180deg) scale(1.1); } 100%{ transform: rotate(360deg) scale(1); } } ``` * 透過兩個重疊但顏色不同的元素,配合 JS 來實現進度條效果 ```css= .music-container .music-info .progress-area{ width:80%; height: 5px; border-radius: 10px; margin-bottom: 15px; background-color: rgb(235, 233, 233); cursor: pointer; } .music-container .music-info .progress-area .progress{ background-color: rgb(145, 206, 245); height: 100%; border-radius: 10px; width: 0%; transition: 0.1s linear; } ``` * 透過添加 class 觸發 aninate 以及 進出場動畫 ```css= .img-container img{ animation-play-state: paused; } /* 在最外層元素加上 play 讓動畫開始 */ .music-container.play .img-container img{ animation-play-state: running; } .music-info{ opacity:0; transition: .3s; } .music-container.play .music-info{ opacity: 1; transform:translateY(100%); } ``` * <font style="color:red">解構賦值</font>抓到對應的key ```javascript= let {a,b,e} = {a: 10, b: 20, c: 30, d: 40, e:65} a; // 10 b; // 10 c; // c is not defined d; // d is not defined e; // 10 ``` [ES6 解構賦值](https://wcc723.github.io/javascript/2017/12/25/javascript-destructuring/) ### 小記 可以作一些補充 * 頁面上添加所有的歌單,直接點擊切換歌曲 * 加上音量功能 * 添加每首歌的秒數以及倒數 * 將旋轉的圖片改為前後各一張的 carousel 也可以透過這邊切歌曲 ### 參考 [HTML\<audio><vedio>Property](https://www.w3school.com.cn/tags/html_ref_audio_video_dom.asp) [timeupdate 事件](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLMediaElement/timeupdate_event)