引言
很早就想了解以下 canvas 中的拖尾效果(如彗星,烟花等效果)是怎么实现的,但是一直没有深入了解,正巧在 codepen 上看到一个 demo,代码简单,效果炫酷,故有此文。
什么黑科技
在我的想象中,实现这种效果是一定需要一个数组的,用来储存彗星的尾巴的位置,透明度,生命时长等信息。然后遍历这个数组,将这个尾巴画在 canvas 上。然而,万万没想到,真正的实现却简单的不像实力派,不需要 数组, 真正起作用来实现拖尾效果的关键是位于 clearCanvas 函数下面的三行代码:
ctx.fillStyle="rgba(0,0,0,0.2)"
ctx.rect(0,0,w,h);
ctx.fill();
这里的技巧在于,在重绘制下一帧前,不是调用clearRect清除掉上一帧的内容,而是在上一帧基础上加上一个半透明蒙层,然后继续画下一帧。画的帧数多了,也就有了拖尾效果,拖尾效果的长短,跟蒙层的透明度有关,透明度越小,拖尾越长。如果你看到这里就明白了,那可以关掉这个页面了,否则的话就跟我一起来实现一个流星吧。
实现一个流星
效果如下:
See the Pen meteor by imgss
(@imgss) on CodePen.
如上所述,这个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,本文完