为通过画布绘制的星星的不透明度添加动画效果



如何为通过画布绘制的星星的不透明度制作动画?我试图在一座山后面画多颗星星。到目前为止,我可以想到 2 个选项。

  1. 我可以使用 2 层图像,并将星星隐藏在山层后面,并在星星的不透明度上使用 css3 关键帧动画。

  2. 通过画布绘制前景(山脉)和背景(星星)。这就是我现在正在采取的方法。

我有 2 个问题。

  1. 星星的不透明度翻转/闪烁速度极快,我可以在动画之间添加延迟吗?目前,我调用无限循环window.requestAnimationFrame(this.animate);我尝试使用setInterval但动画不如requestAnimationFrame

  2. 我最终能阻止这种闪烁效果吗?

这是写在反应组件内部的

// Animation Loop
animate = () => {
window.requestAnimationFrame(this.animate);
this.c.clearRect(0, 0, this.canvas.width, this.canvas.height);
// fill background
this.c.fillStyle = this.backgroundGradient;
this.c.fillRect(0, 0, this.canvas.width, this.canvas.height);
// createmountainRange
this.createMountainRange(1, this.canvas.height - 50, "#384551");
this.createMountainRange(2, this.canvas.height - 150, "#2B3843");
this.createMountainRange(3, this.canvas.height - 250, "#26333E");
this.backgroundStars.forEach(backgroundStar => {
this.draw(backgroundStar);
});
};
//draw function
draw = star => {
const opacity = 1 / utils.randomIntFromRange(1, 10);
this.c.save() // only affects code in between
this.c.beginPath();
this.c.arc(star.x, star.y, star.radius, 0, Math.PI * 2, false);
this.c.fillStyle = `rgba(227, 234, 239, ${opacity})`
this.c.shadowColor = '#e3eaef'
this.c.shadowBlur = 20
this.c.fill();
this.c.closePath();
this.c.restore()
console.log('opacity', opacity)
};
  1. 您可以给每颗星一个单独的属性,以指示何时应重新计算不透明度(该属性也将存储在属性中),并且仅在这些点更改它;可以使用基本缓动(如source * (1 - factor) + target * factor或查找公式)在原始不透明度和新不透明度之间逐渐补间。
  2. 如上所述,您将使用一个条件在不再需要时停止重新计算 alpha。

可以使用单独的画布方法,但前提是您希望所有恒星在任何给定点具有完全相同的alpha;

您可以使用globalAlpha而不是在每次绘制时拼接新fillStyle,这也可能更适合阴影。

您的动画函数有一个帧参数,您可以与 sin 函数一起使用以添加闪烁效果,我需要更多的代码来检查精确的解决方案,但您可以尝试这样的事情:

// Animation Loop
animate = (frame) => {
window.requestAnimationFrame(this.animate);
this.c.clearRect(0, 0, this.canvas.width, this.canvas.height);
// fill background
this.c.fillStyle = this.backgroundGradient;
this.c.fillRect(0, 0, this.canvas.width, this.canvas.height);
// createmountainRange
this.createMountainRange(1, this.canvas.height - 50, "#384551");
this.createMountainRange(2, this.canvas.height - 150, "#2B3843");
this.createMountainRange(3, this.canvas.height - 250, "#26333E");
this.backgroundStars.forEach((backgroundStar, i) => {
this.draw(backgroundStar, i, frame || 0);
});
};
//draw function
draw = (star, index, frame) => {
const opacity = Math.sin(index * frame * 0.01);
this.c.save() // only affects code in between
this.c.beginPath();
this.c.arc(star.x, star.y, star.radius, 0, Math.PI * 2, false);
this.c.fillStyle = `rgba(227, 234, 239, ${opacity})`
this.c.shadowColor = '#e3eaef'
this.c.shadowBlur = 20
this.c.fill();
this.c.closePath();
this.c.restore()
console.log('opacity', opacity)
};

最新更新