Canvas 在为 "source-in" globalCompositeOperation 掩码设置动画时消失

Canvas disappears when animating "source-in" globalCompositeOperation mask

我在 canvas 上使用 "source-in" 合成渐变遮罩,我想为遮罩形状和渐变的拉伸设置动画。这是合成代码,一个名为 drawList:

的函数
var r = ctx.createLinearGradient(1100, 0, 1200 + stretch,0);
r.addColorStop(0,"rgba(255, 255, 255, 1.0");
r.addColorStop(0.8,"rgba(255, 255, 255, 0.0");
ctx.fillStyle = r;
ctx.globalCompositeOperation = "source-in";
ctx.fillRect(300, 0, 1200 + stretch, 1000);

stretch 从 0 开始并使用 requestAnimationFrame 增加动画功能,我已经验证了它在为简单矩形甚至 ctx.clearRect(300, 0, 1200 + stretch, 1000) 设置动画时的效果。动画函数在每次迭代时调用 drawList 并且 drawList.

加载后,drawList 中的列表文本会根据上面矩形的渐变填充淡入淡出。我 运行 遇到的问题是,一旦调用动画函数,canvas 就会被删除并且不会重绘列表。我会使用 ctx.clip(),但我确实需要渐变填充来创建淡入淡出效果。

有什么想法吗?这是canvas的限制吗?

设置 canvas 上下文状态时,例如 globalAlphaglobalCompositeOperationclip 等...这些状态保持活动状态并会影响其余的渲染.解决这个问题的一种方法是在使用完所有状态后重新设置它们。这可能会产生大量额外代码,因此 2Dcontext API 提供了两个方便的函数来控制状态。 ctx.save()ctx.restore()

ctx.save() 将当前状态推入堆栈。 ctx.restore() 弹出最后保存的状态并将 canvas 上下文设置为该状态。您可以嵌套保存,但请记住将每个保存与恢复相匹配。

有关详细信息,请参阅 ctx.save() at MDN

一句警告。如果您追求实时游戏和界面的高性能渲染,则应避免保存和恢复状态。状态更改可能是渲染时的停滞点,或者只是复制不需要的状态更改。恢复状态可能会强制 GPU 从 CPU 内存重新加载 ctx.createPattern() 在先前保存的状态中使用的位图,即使您不打算使用它。这可能会非常慢,并且会对您的帧速率产生重大性能影响,尤其是当您继续恢复到未使用的模式时。