4

是否可以在变量中存储一个矩形以便访问该变量并移动它?就像是:

var rect = new Rect();
/* then in update() method */
rect.x += 5;
rect.y += 5;

这样的事情是否可能,或者您每次都必须使用上下文创建一个新的矩形?如果这是唯一可能的方法,我不明白如何定位画布中绘制的每个矩形。有人可以向我解释一下吗?

4

5 回答 5

2

HTML5 Cancas 有一个位图模型:绘制时修改画布的像素,如果需要,可以读取像素,但丢失了像素(线条、矩形等)的逻辑。

画布模型非常快,可以执行在对象/矢量模型中太长的复杂事情,但限制是您不能更改或删除绘制的对象,如矩形。

如果您想这样做,您需要使用矢量/对象模型,例如 SVG(或普通 DOM 对象)。

如果您想使用画布和对象,一种解决方案是将您的 rect 变量(就像您所做的那样)保存在普通的 javascript 中(在您的画布之外),并在每次更改 rect 时重新绘制整个画布。对于使用画布的应用程序(例如游戏)来说,它是高效且常见的。

这是一个完整的示例:每 10 毫秒移动和重绘 3 个矩形。

http://jsfiddle.net/dystroy/PkzDA/

我让它变得非常简单但干净高效。您可以在真实且快速的应用程序中使用这种逻辑(我愿意)。

于 2012-04-28T19:46:32.920 回答
2

我将保存您要绘制的所有矩形及其坐标的模型。然后,您只需要监听 mouseclick 事件(或 mouseover 事件,无论您需要什么)并浏览模型的每个元素以查看鼠标单击是否在矩形坐标内完成。

正如之前的海报所说,每次想要更改画布时都必须重新绘制画布(尽管您可以通过仅重新绘制感兴趣的区域来加快速度)。希望那有所帮助!

编辑:

你可以定义一个矩形对象:

function Rectangle(x, y, w, h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;

    this.contains = function(x, y) {
        return (x > this.x && x <= (this.x + this.w) &&
            y > this.y && y <= (this.y + this.h));
    }

    this.clone = function() {
        return new Dimension(this.x, this.y, this.w, this.h);
    }
}

然后有一个数组作为你的模型:

var model = [];

然后将你的矩形添加到它:

model.push(new Rectangle(10,10,10,10));//x, y, width, height

然后,当您单击画布时,从鼠标事件中检索鼠标单击坐标,然后循环遍历数组以查看单击是否在其中一个矩形内完成:

for (i = 0 ; i < model.length ; i++) {
 if (model[i].contains(mouseEvent.x, mouseEvent.y))
  //do something like redraw your canvas
}
于 2012-04-28T20:17:45.333 回答
2

我发现本教程确实帮助我理解了这个主题。

http://simonsarris.com/blog/510-making-html5-canvas-useful

他介绍了对象的创建、跟踪状态、处理鼠标事件等。

于 2012-04-28T23:04:02.000 回答
1

如果要在画布上移动矩形,则每次更改 x 或 y 时都需要清除并重绘该矩形。

于 2012-04-28T19:58:23.057 回答
1

首先,您必须将我要说的与@Gaet 说的结合起来

现在关于减少上下文工作:重用相同画布上下文而不删除它的一个选项是更改矩形的绘制方式。

您必须将合成样式更改为“异或”,因此每当您绘制矩形两次时,它都会消失,您将能够将其绘制到新位置。

见下面的例子:

//this will switch context to xor mode
ctx.globalCompositeOperation = 'xor';

//this will paint the rectangle
ctx.fillRect(0, 0, 100, 100);

//this will remove the rectangle
ctx.fillRect(0, 0, 100, 100);
于 2012-04-29T13:50:32.043 回答