Sitemap
來自深淵 (メイドインアビス), 截圖自 巴哈姆特動畫瘋

用canvas寫彈幕

--

在小馬飛去加拿大前約個吃飯,被嘴砲了一番,決定來寫個彈幕壓壓驚。

何謂彈幕

彈幕是一種在影片網站分享評論的形式,在影片播放到指定的時間,會在影片畫面上出現自己的評論,通常是由右至左飛過,也有定格在影片某些位置的形式。我最早看到彈幕功能是在日本的NicoNico,至今也有10年的時間了,之後在中國的bilibili或者巴哈姆特動畫瘋也有彈幕的功能,有些人能夠根據編輯彈幕出現的方式、時間,來達到和影片互動的效果,稱為彈幕職人。

實現方式

直觀上就是在影片上蓋一個透明元素,在上面顯現想要的畫面,元素一般來說有兩種,第一種是操作DOM,另一種是用canvas來畫圖,DOM的方式在網頁上會有效能的問題,巴哈姆特動畫瘋和bilibili是用DOM來實現,我在觀看的時候雖然感受不太到效能問題,但彈幕數量其實也沒有很多,大多在3k到1w上下,如果數量到了5w以上的等級,說不定就會出現效能瓶頸了。

canvas

canvas 是一個渲染點陣的標籤,要在上面畫一些東西,比如說方形,就是呼叫canvas的方法:

const canvas = document.getElementById([element id])
// rendering context
const ctx = canvas.getContext('2d')
//設定填充顏色,線條顏色是strokeStyle
ctx.fillStyle = "rgba(1, 2, 3, .5)"
//畫方型
ctx.fillRect(10, 10, 55, 50)
//寫文字
ctx.fillText("Hello World",10,50)

總之,canvas的方法有很多,可以畫出不同的東西。

requestAnimationFrame

requestAnimationFrame API提供了一個畫動畫很好的接口,它會回傳一個ID,透過不斷的呼叫render function來達到動畫的效果,效能上在某些瀏覽器和CSS3是差不多的[注1],當然也比setTimeInterval好很多,而幀數則根據瀏覽器環境而定,通常是60fps,如果要改變幀數,則要在render function中做時間判斷來改變呼叫頻率。

如果要暫停requestAnimationFrame ,則呼叫cancelAnimationFrame(ID) 。

Get b2’s stories in your inbox

Join Medium for free to get updates from this writer.

[注1] :

canvas 比例

如果使用CSS改變canvas長寬,會改變畫布的比例,解決方法是手動建立canvas元素,並在標籤內給定長寬,或用js設定長寬。

video element Event

透過監聽video的事件來達成渲染彈幕的行為甚至是自訂播放器外觀,列出一些video常用到的事件:

  1. play:從暫停到播放的事件
  2. playing:正在播放
  3. seeked:拖放完時間軸
  4. seeking:正在拖拉時間軸
  5. pause:影片暫停

更詳細的說明,請上:

requestFullscreen

如果用內建播放器的全螢幕,則只能看到video,所以需要自己呼叫requestFullscreen來放大想顯示的元素,requestFullscreen每家瀏覽器實作不太一樣,還需要自己寫polyfill,像chrome是webkitRequestFullscreen 。全螢幕時會觸發事件fullscreenchange ,可以用來做一些畫面調整。另外CSS也有提供:fullscreen的偽類,方便對全螢幕的元素做外觀上的調整。

reference

--

--