6

好吧,我承认我试图变得聪明:我想如果我覆盖 Shape 的 drawFunc 属性,我可以简单地在矩形内绘制任何内容,并且仍然使用 KineticJS 的点击检测。这是我的尝试:

var shape = new Kinetic.Shape({
  drawFunc: function(context) {
    var id = 26;  // Id of a region inside composite image.
    context.beginPath();
    context.rect(0, 0, w, h);
    context.closePath();
    this.fill(context);
    this.stroke(context);
    context.drawImage(copyCanvas, (id % 8) * w, flr(id / 8) * h, 
        w, h, 0, 0, w / 2, h / 2);
  },
  draggable: true
});

因此,想法是绘制一个矩形,并使用 drawImage() 在矩形顶部绘制一些东西(就像纹理一样,除了它会不时更改,因为 copyCanvas 本身会发生变化)。与此同时,我希望事件处理(尤其是拖放)仍然“正常工作”。好吧,这就是发生的事情:我的 drawImage() 未覆盖的矩形部分正确检测到点击。但是,图像覆盖的矩形的四分之一拒绝响应点击!现在,我的问题是为什么?我深入研究了 KineticJS 代码,并认为点击检测只是意味着绘制到缓冲区并查看给定的 x、y 点是否具有非零 alpha。我看不出这会受到我在矩形顶部绘制图像的影响。

有什么想法吗?

4

2 回答 2

2

好的,所以我继续查看源代码。这是确定的答案:

KineticJS 为使用从 RGB 颜色到形状对象的全局映射创建的每个形状分配随机且唯一的 RGB 颜色。形状的draw()函数被调用了两次:一次使用“真实”画布,一次使用用于命中检测的“缓冲”画布。当使用“缓冲区”画布时,KineticJS 将笔触和填充颜色切换为给定形状的唯一 RGB 颜色。同一个“缓冲”画布用于图层上的所有形状。因此,命中检测只是读取给定点的 RGB 值并在全局地图中查找相应的形状。现在,在我的示例中,我以一种绕过 KineticJS 用于命中检测的颜色杂耍的方式绘制了一个图像。因此,当我点击图像区域时,

解决方案不是为“缓冲区”(或“命中检测”)阶段绘制图像:一个简单的矩形就可以了。如果您想知道,这里是正确的代码drawFunc

var width = 200;
var height = 100;
var myShape = new Kinetic.Shape({
  drawFunc: function(context) {
    if (layer.bufferCanvas.context == context) {
      context.beginPath();
      context.rect(0, 0, width, height);
      context.closePath();
      this.fill(context);
      this.stroke(context);
     } else {
       context.drawImage(someCanvasWithAnythingOnIt, 0, 0, width, height,
         0, 0, width, height);
     }
  }});

我可以领取自己的奖励吗?

于 2012-10-28T20:46:22.863 回答
0

我认为你的问题在于顺序。您绘制的每个对象都有一个深度,默认排序就像一个堆栈,最后绘制的是在顶部。现在您已经修改了代码,在 shape draw 函数中进行了 2 次绘制,我仍然认为保留了顺序,因此对象无法检测到输入。尝试更改顺序,即先绘制图像,然后绘制矩形,看看问题是否解决。否则,以 jsFiddle 为例。

于 2012-10-28T12:01:29.763 回答