引言
很早就想了解以下 canvas 中的拖尾效果(如彗星,煙花等效果)是怎么實現的,但是一直沒有深入了解,正巧在 codepen 上看到一個 demo,代碼簡單,效果炫酷,故有此文。
什么黑科技
在我的想象中,實現這種效果是一定需要一個數組的,用來儲存彗星的尾巴的位置,透明度,生命時長等信息。然后遍歷這個數組,將這個尾巴畫在 canvas 上。然而,萬萬沒想到,真正的實現卻簡單的不像實力派,不需要 數組, 真正起作用來實現拖尾效果的關鍵是位於 clearCanvas 函數下面的三行代碼:
ctx.fillStyle="rgba(0,0,0,0.2)"
ctx.rect(0,0,w,h);
ctx.fill();

這里的技巧在於,在重繪制下一幀前,不是調用clearRect清除掉上一幀的內容,而是在上一幀基礎上加上一個半透明蒙層,然后繼續畫下一幀。畫的幀數多了,也就有了拖尾效果,拖尾效果的長短,跟蒙層的透明度有關,透明度越小,拖尾越長。如果你看到這里就明白了,那可以關掉這個頁面了,否則的話就跟我一起來實現一個流星吧。
實現一個流星
效果如下:
如上所述,這個demo也是在繪制完一幀后,繪制下一幀之前,添加一層半透明蒙層,最終形成拖尾的效果
function draw() {
// 繪制流星
for(let star of stars){
star.draw()
star.move()
}
// 這里在不斷加半透明蒙層,使上一幀的流星變淡
ctx.fillStyle = 'rgba(0,0,0,0.1)'
ctx.rect(0,0,800,600)
ctx.fill()
requestAnimationFrame(draw)
}
全部代碼見codepen,本文完