有没有办法轻松确定单击画布上绘制的形状?

时间:2011-03-10 00:32:28

标签: html5 canvas interaction

我正在学习如何使用HTML5画布。我有一个简单的脚本,它沿着水平线绘制圆圈。

我想将脚本增强为更具互动性。我希望能够点击该行中的一个圆圈,这会导致链接到该圆圈的数据在画布上显示为文本。

这是否可以在画布中轻松实现?从我看过的教程中我得知,我必须在画布上放一个onclick。从那里我猜测我必须找出鼠标光标被点击的地方,并以某种方式确定哪个圆圈包含我点击的点。

是否有任何代码或指针片段可以帮助我解决这个问题?或者,画布真的不适合这类问题吗?任何评论都非常感谢。

4 个答案:

答案 0 :(得分:3)

您可以使用canvas的isPointInPath方法添加鼠标事件处理。下面是这样的(未经测试)。

// add click event handler to canvas
// on click
var rect = canvas.getBoundingClientRect();
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;

ctx.beginPath()
// draw stuff
if (ctx.isPointInPath(mouseX, mouseY)) {
  // handle click
}

这将识别任何形状,如果您绘制除矩形和圆形以外的任何形状,这将非常有用。但是,这样做的主要缺点是必须在每次单击时重绘(如果要添加鼠标悬停,则需要移动鼠标)。根据我的经验,在开始发现性能问题之前,我可以汲取至少300个对象。

我还应该注意到isPointInPath的firefoxes实现中有一个bug由于某种原因仍未解决。但幸运的是,修复很容易

CanvasRenderingContext2D.prototype.isPointInPath_mozilla = function( x, y )
{
  if (navigator.userAgent.indexOf('Firefox') != -1){
    this.save();
    this.setTransform( 1, 0, 0, 1, 0, 0 );
    var ret = this.isPointInPath( x, y );
    this.restore();
  } else
    var ret = this.isPointInPath( x, y );

  return ret;
}

用ctx.isPointInPath_mozilla(x,y)替换ctx.isPointInPath(x,y),一切正常

答案 1 :(得分:2)

Canvas使用光栅图形。一旦你绘制了一个圆圈,它就不再具有圆圈的身份 - 你只有一堆像素。你需要自己跟踪所有形状。

如果使用矢量图形(如SVG),形状将保留一个标识并可以进行操作。这种方式可能会更容易。

答案 2 :(得分:0)

您为画布创建单击事件,并且在处理程序中,如果用户单击圆圈,则必须计算(某些基本数学运算)。另一种方法是不使用画布,但SVG有像raphael这样的库可以提供帮助。

答案 3 :(得分:0)

我已经为移动设备画布绘制和形状匹配做了类似的事情。

我的程序是。

根据画布高度和宽度(以像素为单位)声明一个2D数组。

用0

填充数组

对于mousemove事件(桌面浏览器)跟踪位置。您将获得X,Y值。 在你的2D数组中,在行和列中放置1(X和Y值)。

绘图后,您将获得2D二进制图像阵列。

现在有趣的部分:

从此链接尝试Image momentam或任何其他合适的方法。 http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/Tutorial--Algorithms%20for%202-D%20Object%20Recognition.pdf

如果您保存一些2D绘制的形状数组并与当前绘制的图像匹配,您将能够找到最接近的匹配。如果用户绘制完全不同的形状,请尝试找到合适的阈值。

我希望这会有所帮助。