你們年前好,立刻就要元旦了,在好久沒有寫文章以後,想到這篇文章將會成爲本人今年的
絕響也是有點蛋疼。不過也好,畢竟本人算不得什麼勤快的生物,並且比起那些大神來講也差遠了,就做爲本身工做半年後的一次沉澱算了。css
文中有些思想可能不見得是最好的解決辦法,大神們請輕噴。linux
這個項目原本是我本身準備的一個開源插件,但因爲上班寫這個的過程當中被老闆發現了(∑(O_O;)),就說把這個東西寫成公司用的吧,而後,而後開源就GG了(我了個大擦,我說我這個是本身的項目也沒用),雖說也能夠偷偷放出來,但畢竟我還在職,就原諒我此次沒辦法把代碼放出來吧。我會在講解過程當中儘量講解詳細的。以上。。。。開始一波交♂易吧,騷年們(手動滑稽)android
demo : 我是你親愛的demo (彈幕數2000)ios
至少須要有canvas和js的編程經驗,而後養成一個好的代碼習慣(否則一段時間後你都不知道你本身幹了什麼),下面講解的內容不會涉及到具體程序和功能的編寫,更多地是在強調性能優化這方面,徹底當教程看的能夠略過了。。。大神請隨意css3
其實實現彈幕的方式能夠有多種,好比說用dom和canvas實現都是能夠的,但咱們這裏選取的是canvas來繪製彈幕。chrome
考慮到dom 只適合在單位時間內繪製少許彈幕 ,這對於咱們播放器來講明顯是不合需求的。其實去過B站的都知道,由於播放器有時會出現短期內的「彈幕轟炸」,你想一想若是是用dom來寫,頁面瞬間建立幾百個、甚至上千個element。。。那酸爽,簡直讓人不敢相信。。。因此說,dom只適用於那些對時間把握要求不那麼高的項目,由於你能夠經過控制單位時間內彈幕的繪製數量來達到緩解性能的目的。編程
使用canvas好處有幾點: 1.不用頻繁的操控dom元素 2.有強大的api,操做簡單 3.在移動設備上也能比較高性能地運行 4.強化你的代碼組織能力(如何更好地分離功能什麼的,而不是加個css3動畫就了事)
其實最簡單的就體如今api上,好比說實現全屏模式,其實android和ios到目前爲止都仍是不支持元素全屏的,因此說你這裏要考慮 requestFullScreen 不能用的狀況下,對移動設備的降級處理。還有一點就是移動設備和PC的性能差距仍是有點大的,這就須要你考慮在某些消耗性能的功能和用戶體驗之間作些取捨。canvas
其實這裏也是考慮各個主流瀏覽器的性能差別,對某些功能作出適當的調整。其實在使用canvas text API的時候,有些效果的使用是會大大地加劇瀏覽器的負擔,好比說:文字陰影、漸變、變換等;不見得每一個瀏覽器都能很迅速的繪製出你想要的效果,即便在你本身看起來不怎麼須要時間。 這裏,chrome內核的瀏覽器表現極其優秀,反而讓我一臉懵逼的是火狐。。在這我整理了一些主流瀏覽器在繪製方面的差別(參考數據):api
upperNum : { //當彈幕數超過必定數額時,取消文字的全局特效(如陰影等) //ps:火狐爸爸不給力啊,向谷歌勢力低頭 "firefox" : 500, "safari" : 800, "chrome" : 2000, "ie" : 900, "edge" : 1100 }, scale : 1, rotate : 0
從上面能夠看出,其實瀏覽器性能之間的差別仍是有的,此時就須要咱們根據數據的多少來調整特效的展示,你能夠分別用火狐和chrome打開demo頁面看效果瀏覽器
如全局文字顏色等一些能在循環體外設置的api,就千萬不要放到循環體內部去給每一個彈幕單獨設置(除非全局樣式發生了改變)。
還有就是優化循環,沒錯,就是優化循環。。。。。當你的彈幕池達到數千甚至上萬的時候,你一個循環就能浪費掉許多時間,其實有些條件達到的時候你是不必再進行循環了的。對於視頻彈幕來講,咱們須要的只是 「把某一個時間點的全部彈幕進行一次繪製」,這樣咱們就已經確立了一部分優化原則:在當前播放時間以前的彈幕我不須要管,在當前播放時間以後的彈幕我不須要管。至於怎麼實現,咱們能夠改變for循環的start下標來達到忽略前面的彈幕,能夠經過判斷當前彈幕的時間和播放器時間的大小來達到跳出循環的目的。 在下面的循環體代碼(部分)就能夠看出來優化的操做
if(!this.Canvas.globalStyleHasChanged) Canvas.setBaseTextStyle(cxt); //設置文字基本樣式,咱們在這裏設置好統同樣式 //我這裏是彈幕循環 for( var i = DMsystem.idx, DM; DM = DMs[i++]; ){ if( DM.currentTime > currentTime ){ break; } if( DM.currentTime < currentTime && !DM.isDisplaying ){ DM.hasShowed = true; continue; } DMsystem.refresh(DM); //更新位置 Canvas.drawDM(cxt,DM,options); //繪製 DMsystem.recovery(DM,currentTime); //判斷彈幕是否顯示完畢並回收相關行 }
其實在這一版以前我還寫過1.0版,不過在移動設備上的性能太糟糕因此捨棄了(大家能夠用手機打開這一版demo看看效果,性能其實仍是能夠的),緣由是我把每一條彈幕都new了一個實例。。。當時忙着js的僞面向對象編程實踐:「彈幕嘛,每一條彈幕都應該是一個成熟的個體,不只有本身獨特的顏色,還有所在的位置.....」。而後呢?當我把彈幕數調整爲5000的時候---而後就沒有而後了。。。。too young too simple,sometimes naive.....瀏覽器直接炸掉了。。。。。因此說咱們在面向對象的時候要考慮哪些纔是真正應該new的。。(儘管看起來好像就我本身有點蠢....)
以上就是要寫的全部的東西了,儘管我知道各位看起來可能有點不那麼方便(畢竟代碼少,並且講得很籠統),當你本身開始寫的時候就會明白項目中大部分東西都很簡單(各類api的調用),真正麻煩的仍是性能的優化,以及對設備和瀏覽器差別的處理。。若是不懂的話歡迎留言詢問,我這個還不是最終版,接下來還要加入模式的切換。。。好比說 直播播放器模式(live)和視頻播放器模式(player)的優化細節又有點不同,還有高級彈幕的處理(圖片,圖形等)。。後續有空閒時間可能會繼續更新,最後再說一次------------提早祝你們新年快樂