我现在正在学习如何使用 HTML5 画布。我有一个简单的脚本,它沿着水平线绘制圆圈。
我想增强我的脚本以更具交互性。我希望能够单击沿线的圆圈之一,这会导致链接到该圆圈的数据在画布上显示为文本。
这在画布中很容易实现吗?从我看过的教程中,我了解到我必须在画布本身上放置一个 onclick。从那里我猜我必须找出我的鼠标光标被点击的位置,并以某种方式找出哪个圆圈包含我的点击点。
是否有任何代码片段或指针可以帮助我解决这个问题?或者,画布真的不适合这类问题吗?任何意见都非常感谢。
我现在正在学习如何使用 HTML5 画布。我有一个简单的脚本,它沿着水平线绘制圆圈。
我想增强我的脚本以更具交互性。我希望能够单击沿线的圆圈之一,这会导致链接到该圆圈的数据在画布上显示为文本。
这在画布中很容易实现吗?从我看过的教程中,我了解到我必须在画布本身上放置一个 onclick。从那里我猜我必须找出我的鼠标光标被点击的位置,并以某种方式找出哪个圆圈包含我的点击点。
是否有任何代码片段或指针可以帮助我解决这个问题?或者,画布真的不适合这类问题吗?任何意见都非常感谢。
您可以使用画布的 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 个对象。
我还应该注意,在 Firefox 的 isPointInPath 实现中存在一个错误,由于某种原因仍未修复。但幸运的是,修复很容易
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) 就可以了
Canvas 使用光栅图形。一旦你画了一个圆圈,它就不再具有圆圈的身份——你只有一堆像素。您需要自己跟踪所有形状。
如果您使用矢量图形(如 SVG),则形状会保留身份并且可以进行操作。这种方式可能会更容易。
我已经为移动设备画布绘制然后形状匹配做了类似的事情。
我的程序是。
根据画布高度和宽度(以像素为单位)的数量声明一个二维数组。
用 0 填充数组
对于 mousemove 事件(桌面浏览器)跟踪位置。您将获得 X,Y 值。在您的二维数组中,将 1 放入行和列(X 和 Y 值)。
绘制完成后,您将获得一个 2D 二值图像数组。
现在有趣的部分:
从此链接尝试 Image momentam 或任何其他合适的方法。http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/Tutorial--Algorithms%20for%202-D%20Object%20Recognition.pdf
如果您保存一些 2D 绘制的形状数组并与当前绘制的图像匹配,您将能够找到最接近的匹配。如果用户绘制完全不同的形状,请尝试找到合适的阈值。
我希望这会有所帮助。
您为画布创建单击事件,如果用户单击圆圈,则必须在处理程序中计算(一些基本数学)。另一种方法是不使用画布,但 SVG 有像raphael这样的库可以提供帮助。