請忽略下面這段文字
年關將至,時間好歹又多出了些許。卻不敢過分消遣。歲月不曾饒過我,我亦不想饒過歲月。且將它塞得膨脹,讓這一年看似加更充實。
未曾料想我一個愛些風花雪月、研墨行歌之人,卻作起了碼農這一行當。雖作了碼農,卻斷不了嗜好,日日必聽歌。奈何近日,公司限制高流量網絡訪問。蝦米、網易雲、QQ甚至酷狗,無一倖免。
沒有了歌,變得像捱了錘的牛同樣,疲軟成一灘爛泥。
所幸還能用用listen 1,可這listen 1卻讓人味同嚼蠟。歌且無過,想是這界面不合胃口。作一名前端,也沾了對外觀挑三檢四的毛病。
因而靈光一閃,便想造一個出來。css
項目地址:https://github.com/ermu592275...
演示地址:https://ermu592275254.github....(因referer限制,沒法搜索歌曲)html
作音樂播放器,界面必定要炫酷。太low了聽歌沒感受。自己是爲了在上班的時候用,因而作成了一個相似網易雲音樂的界面,大小合適。不用兼容手機端。前端
本懷着簡單實用的需求去考慮,圖標可用SVG、url或者css。相對於url,SVG和css更好一些。爲了修煉,最終選擇的css。利用好after和before,能減小不少dom嵌套。vue
.next { position: relative; display: inline-block; height: 36px; width: 36px; border: 2px solid #fff; border-radius: 20px; -webkit-border-radius: 20px; -moz-border-radius: 20px; } .next:before { content: ''; height: 0; width: 0; display: block; border: 10px transparent solid; border-right-width: 0; border-left-color: #fff; position: absolute; top: 8px; left: 10px; } .next:after { content: ''; height: 20px; width: 4px; display: block; background: #fff; position: absolute; top: 8px; left: 22px; }
網易雲的唱片很好看,我也要弄一個唱片!
用好box-shadow,一個元素即可以作成很好看的唱片效果。html5
.disc { position: relative; margin-top: 10%; margin-left: 10%; width: 300px; height: 300px; border-radius: 300px; transform: rotate(45deg); background-image: radial-gradient(5em 30em ellipse, #fff, #000); border: 2px solid #131313; box-shadow: 0 0 0 10px #343935; opacity: 0.7; }
audio自己的樣式很難看,而且不一樣的瀏覽器呈現出來的效果也不同。固然你能夠修改audio的樣式,傳統的作法是經過controls屬性來隱藏audio,而後用div來代替。如今是html5時代了,固然要用更符合場景的新元素————range。node
input[type=range] { -webkit-appearance: none; width: 80%; height: 8px; border-radius: 10px; background-color: #fff; } input[type=range]::-webkit-slider-thumb{ -webkit-appearance: none; } input[type=range]::-webkit-slider-runnable-track { height: 8px; border-radius: 20px; } input[type=range]:focus { outline: none; } input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; margin-top: -3px; height: 14px; width: 14px; background: #eb7470; border-radius: 50%; border: solid 3px #fff; box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.5); }
將圖片設置爲背景的感受很棒,能夠說整個播放器的顏值這背景提供了一半。設置也很是簡單,用到了css3的濾鏡。webpack
.bg-blur { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100%; height: 100%; background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(20px); z-index: -1; }
背景圖片經過js控制。css3
<div class="bg-blur" :style="`background-image:url(${currentSong.album_logo})`"></div>
直接去蝦米官網打開network,將url複製到postman裏面去作請求。經過修改headers發現,會校驗Referer。也就是說只有蝦米容許的域名能夠訪問此接口。
http://api.xiami.com/web?v=2....git
由於接口支持jsonp。起初嘗試將chrome瀏覽器設置跨域,而後經過$.ajax去作一個jsonp的請求。能夠正常訪問。
以後忽然不行了,是否是蝦米作了限制?
遂改用node啓動一個服務,去僞造referer發起請求,再將請求轉發到頁面。無心中寫了一個代理。github
... case '/song': let songOptions = { url: 'http://api.xiami.com/web?'+ urlArr[1], headers: { 'Referer': 'http://m.xiami.com/' } }; function callback1(error, response, body) { if (!error && response.statusCode == 200) { res.end(body); } } request(songOptions, callback1); break; ...
做爲一款逼格比較高的播放器,歌詞滾動是必須的。
將每一句歌詞保存爲一個對象,有對應的時間。當歌曲播放的當前時長大於或等於歌詞的時間,小於此歌詞的下一句歌詞的時間,那麼就將此歌詞滾動到可視區域。而且修改字體顏色。
接口返回的歌詞一臉懵逼,仔細研究一下,發現是有規律的。
[ti:aLIEz] [ar:SawanoHiroyuki[nZk]:mizuki] [al:o1] [ly:澤野弘之] [mu:澤野弘之] [ma:] [pu:] [by:ttpod] [total:268512] [offset:0] [00:00.000]<195>aLIEz <199>- <451>SawanoHiroyuki[nZk]:mizuki [x-trans]徹頭徹尾的謊話 - SawanoHiroyuki[nZk]:mizuki [00:01.095]<201>做<250>詞<200>:<201>澤<200>野<199>弘<300>之 [x-trans] [00:02.846]<200>做<150>曲<150>:<200>澤<200>野<351>弘<349>之 [x-trans] [00:20.828]<200>決<250>め<200>つ<201>け<149>ば<201>か<349>り [x-trans]一直專斷專權 [00:23.279]<200>自<200>惚<200>れ<200>を<200>着<400>た [x-trans]老是自負逞強 [00:24.979]<200>チ<200>ー<200>プ<450>な<550>hokori<350>で [x-trans]明明只是一文不值的驕傲 ...... refactoringLyrics(lyric){ let text = lyric.split('[offset:0]')[1]; let textArr = text.split('\n'); let lyricsArr = [], translate = []; textArr.forEach((item, index) => { let time = 0, text = ''; if (item.indexOf('[x-trans]') > -1) { translate.push(item.split('[x-trans]')[1]) } else if (item.trim() != '') { time = item.slice(1, 6).split(':'); time = parseInt(time[0]) * 60 + parseInt(time[1]); text = item.slice(11); let arr = text.split('>'); let str = arr.reduce((a, b) => { return a.split('<')[0] + b.split('<')[0] }); let obj = { time: time, text: str }; lyricsArr.push(obj); } }); for (let i in translate) { lyricsArr[i].text = lyricsArr[i].text + '\n' + translate[i]; } this.currentLyrics = lyricsArr; },
爲了遵循模塊化開發,決定將搜索欄寫成一個子組件。在同一頁面下寫子組件,子組件掛載到對應的template就有講究了。此template不能被父組件的掛載元素包含,不然父組件渲染時會由於沒法渲染子組件中的數據而報undefined。
<div id="app" class="main"> ... </div> <template id="search-box"> ... </template> var searchBox = { template: '#search-box', props: { isShow: Boolean, openFun: Function }, data(){ return { resultList: [], searchValue: '', } }, methods: { } }; new Vue({ el: '#app', components: { 'com-tip': tip, 'search-box': searchBox }, ... })
經過jsonp去請求數據,須要設置一個callback函數,此callback寫成一個全局函數,若是不這樣寫,而是經過
searchBox.methods.callback的形式,this指向將爲methods。而沒法直接給searchBox的data賦值。
因而經過eventBus來處理,這樣更易維護。
var EventBus = new Vue(); var callBack = function(result) { console.log(result); EventBus.$emit('callBack', result); }; ... mounted(){ let self = this; EventBus.$on('callBack', function(res) { if (res && res.data) { self.resultList = res.data.songs; } }) } ...
下次再打開,應該播放列表應該保留上一次的數據,這個可直接用localstrong實現
濾鏡模糊 http://www.zhangxinxu.com/wor...
css圖標 http://www.uiplayground.in/cs...
flex 兼容寫法: https://www.cnblogs.com/irisz...
flex 佈局教程 http://www.ruanyifeng.com/blo...
滑動條樣式自定義 http://blog.csdn.net/u0133472...
隱藏滾動條兼容 https://segmentfault.com/q/10...
audio屬性 https://developer.mozilla.org...
audio事件 https://developer.mozilla.org...
使用cdn,vue的prop只支持中線格式,駝峯格式不生效
ps: 在用webpack打包的項目中用駝峯是能夠,在打包過程當中,會作處理。
// 正確寫法 <search-box :is-show="showSearch" :open-fun="openSearch" @push-song="pushNewSong" @play-song="playSong"></search-box> // 錯誤寫法 <search-box :isShow="showSearch" :openFun="openSearch" @pushSong="pushNewSong" @playSong="playSong"></search-box>
手動修改進度,偶爾會不生效。
搜索暫不支持分頁
不支持建歌單
背景顏色與進度條顏色相近需修改進度條顏色
不支持播放模式選擇-單曲循環-隨機播放