代码之家  ›  专栏  ›  技术社区  ›  Seph Reed

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

  •  2
  • Seph Reed  · 技术社区  · 7 年前

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

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

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

    我检查过这些:

    Canvas Fade Out Particles

    FadeIn FadeOut in Html5 canvas -问题在于如何淡入/淡出画布上的图像,而不是画布内容本身。

    编辑:我想我可能找到了一个解决办法: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing

    1 回复  |  直到 7 年前
        1
  •  2
  •   Seph Reed    7 年前

    合成完成了。这里是淡出阶段:

    // 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();
    

    通过使用“目的地在”复合模式绘制形状,新形状的不透明度将应用于背景。

    https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing

    also on CodePen ):

    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    canvas.width = 300;
    canvas.height = 300;
    
    ctx.fillStyle = "rgb(250, 0, 0)";
    // rectangle is filled with solid red
    ctx.fillRect(50, 50, 100, 100);
    
    ctx.globalCompositeOperation = "destination-in";
    ctx.fillStyle = "rgba(250, 250, 250, 0.5)";
    ctx.fillRect(75, 75, 100, 100);
    // after the line above, only the part where the two squares show is overlappped, and it only has the opacity of the latter square.  Doing this many frames in a row fully fades out the background.
    ctx.globalCompositeOperation = "source-over"
    
    document.getElementById("test").appendChild(canvas);
    <div id="test"></div>