html5 canvas - 保存路径或剪辑区域以便重用

时间:2011-09-19 21:13:05

标签: javascript html5 optimization canvas

我目前正在我正在开发的游戏中实现2d可变形地形效果,并且它可以正常运行,但我可以设想它变得非常快,因为我开始添加更多层效果。

现在我正在寻找的是一种可能保存路径或剪贴蒙版或类似物的方法,而不必将路径的每个点存储在我需要通过每个帧绘制的地形中。随着我添加更多图层,我将越来越多地遍历路径,这可能包含数千个点。

一些非常简单的代码来演示我正在做的事情

for (var i = 0; i < aMousePoints.length; i++)
{
    cRenderContext.save();
    cRenderContext.beginPath();
    var cMousePoint = aMousePoints[i];
    cRenderContext.arc(cMousePoint.x, cMousePoint.y, 30, 0, 2 * Math.PI, false);
    cRenderContext.clip();
    cRenderContext.drawImage(cImg, 0, 0);
    cRenderContext.closePath();
    cRenderContext.restore();
}

基本上我正在采用一种有效的方法在每帧上方为我的图像绘制剪贴蒙版

3 个答案:

答案 0 :(得分:13)

注意除了x / y位置之外,剪切区域保持完全相同。这是一个很大的优点。

剪切区域是使用context.save()context.restore()保存和恢复的内容之一,因此可以以这种方式保存(换句话说,只定义一次)。当您想要放置它时,您将使用ctx.translate()而不是arc的x,y。

但是第二种方式可能更有效:

  1. 有一个内存中的画布(从未添加到DOM或显示在页面上),仅用于包含剪辑区域并且是裁剪区域的大小
  2. 将剪切区域应用于此内存中画布,然后将图像绘制到此画布上。
  3. 然后将drawImage与内存中的画布一起使用到游戏上下文中。换句话说:cRenderContext.drawImage(in-memory-canvas, x, y);其中x和y是合适的位置。
  4. 因此,裁剪区域始终保持在同一位置并且只被绘制一次。图像在剪切画布上移动,然后绘制以使其看起来正确,然后将内存中的画布绘制到主画布上。它应该快得多,as calls to drawImage are far faster than creating and drawing paths.

    作为单独的性能考虑因素,除非必须,否则请勿致电saverestore。它们确实需要时间,而且在上面的循环中它们是不必要的。

    如果你的代码是开源的,请告诉我,如果你愿意,我会一般地看一下它的性能。

答案 1 :(得分:11)

为什么不为前景设置一个画布,为背景设置一个画布?如下面的演示

Foreground/Background Demo (我可能会有点过分进行演示:?我喜欢搞乱JS / canvas。

但基本上前景画布除了内容之外是透明的,因此它就像背景画布上的一个遮罩。

答案 2 :(得分:5)

现在可以使用新的path2D对象。

新的Path2D API(可从Firefox 31+获得)允许您存储路径,这简化了画布绘制代码并使其运行更快。构造函数提供了三种创建Path2D对象的方法:

new Path2D();     // empty path object
new Path2D(path); // copy from another path
new Path2D(d);    // path from from SVG path data

第三个版本,它采用SVG路径数据构建,特别方便。您现在可以重新使用SVG路径直接在画布上绘制相同的形状:

var p = new Path2D("M10 10 h 80 v 80 h -80 Z");

信息来自Mozilla official site