Javascript 在画布上设置动画时,淡出画布上传递的帧的最有效方法是什么?

Javascript 在画布上设置动画时,淡出画布上传递的帧的最有效方法是什么?,javascript,animation,canvas,Javascript,Animation,Canvas,我正在使用HTML画布制作类似于可视化工具的东西。在绘制每个帧时,我希望获取当前画布数据并将其淡出 我发现了几种获得这种效果的方法: 在整个画布上绘制背景色的半透明框。实际上不会淡出内容,因此画布后面的任何内容都会被覆盖。这已经足够快了,而且可以做到这一点证明浏览器能够进行所有必要的计算 使用canvas.getImageData(),操作图像数据,然后使用canvas.putImageData()重新应用它。这样做非常低效,将大量本应是本机逻辑的内容放入js中。太慢了,不能真正使用 使用can

我正在使用HTML画布制作类似于可视化工具的东西。在绘制每个帧时,我希望获取当前画布数据并将其淡出

我发现了几种获得这种效果的方法:

  • 在整个画布上绘制背景色的半透明框。实际上不会淡出内容,因此画布后面的任何内容都会被覆盖。这已经足够快了,而且可以做到这一点证明浏览器能够进行所有必要的计算

  • 使用canvas.getImageData(),操作图像数据,然后使用canvas.putImageData()重新应用它。这样做非常低效,将大量本应是本机逻辑的内容放入js中。太慢了,不能真正使用

  • 使用canvas.toDataUrl()生成图像(png/jpg),并使用ctx.globalCapacity以一定的透明度重新绘制该图像。将画布数据转换为图像并返回的步骤非常昂贵(压缩、标题等)。太慢了,不能真正使用

  • 如何在画布上淡出已传递的帧,同时在顶部设置新帧的动画?

    我已经检查了这些:

    -非常类似的问题,答案建议对我的问题采用不适用的解决方案(使用精灵并重新绘制整个画布)

    -问题在于在画布上淡入/淡出图像,而不是画布内容本身

    编辑:我想我可能已经找到了一个解决方案:
    合成成功了。这里是淡出阶段:

    // painter = canvas.getContext("2d")
    painter.save();
    painter.globalAlpha = 1;
    painter.globalCompositeOperation = "destination-in";
    const fadeOutAmount = 0.99;
    painter.fillStyle = "rgba(0, 0, 0, fadeOutAmount)";
    painter.fillRect(0, 0, canvas.width, canvas.height);
    painter.restore();
    
    通过使用“destination in”合成模式绘制形状,新形状的不透明度将应用于背景

    示例():

    const canvas=document.createElement(“canvas”);
    const ctx=canvas.getContext(“2d”);
    画布宽度=300;
    帆布高度=300;
    ctx.fillStyle=“rgb(250,0,0)”;
    //矩形用实心红色填充
    ctx.fillRect(50,50,100,100);
    ctx.globalCompositeOperation=“目的地在”;
    ctx.fillStyle=“rgba(250250250,0.5)”;
    ctx.fillRect(75,75,100,100);
    //在上面的线之后,只有两个正方形显示的部分重叠,并且它只有后一个正方形的不透明度。执行此操作时,一行中的许多帧会完全淡出背景。
    ctx.globalCompositeOperation=“源代码结束”
    document.getElementById(“测试”).appendChild(画布)
    
    第二个示例使用的是
    ctx.globalAlpha
    。是我用来淡出整个画布的。第一个示例是使用rgba和hsla颜色逐个淡出粒子。建议使用canvas.getImageData()和canvas.putImageData()。这在效率上是极其昂贵的。你也可以使用cssopacity@enxaneta我想使用ctx.globalAlpha淡出整个画布,但获取图像数据(我能找到)的唯一方法是首先转换为png。当我运行该命令时(无论是在CodePen上还是在堆栈片段中,我将CodePen复制到其中的答案),我只看到一个矩形,没有淡入操作。。。?(我还尝试在其他操作之前将画布放入DOM中,但这没有改变任何事情。)尝试注释掉
    ctx.fillRect(75,75,100,100)行。你会看到一个更大的未经修饰的红场。我将添加一些注释,谢谢。不过我很困惑。你不是说你想让它褪色吗?一个不在上面。(我真的很想看到这一切发生,是吗?:-)这是一帧值得褪色的画面。这真的只是证明它是有效的。如果它完全淡出,它将在加载页面后很快消失,并且不再显示,这似乎更令人困惑。