我正在开发一个 HTML5 画布应用程序。我现在能够找到我在画布上单击的任何点的坐标和十六进制值。如果假设我正在单击一个具有填充多边形的区域(并且我知道多边形的颜色)。有什么方法或算法可以返回绘制多边形的封闭坐标?
问问题
385 次
1 回答
3
解决方案
将多边形点存储在对象或数组中并使用 canvas 方法:
var boolean = context.isPointInPath(x, y);
通过将点存储为对象/数组,您可以简单地遍历集合以重新构建每个多边形的路径,然后调用上面的方法(无需重新绘制多边形进行检查)。
如果你有一个命中,那么你知道它是哪个对象,因为它会是当前的。您可以在这些对象上存储其他元数据,例如颜色。
例子
您可以创建一个简单的类来存储坐标和颜色(可以根据需要扩展的基本对象):
function Polygon(pts, color) {
this.points = pts;
this.color = color;
return this;
}
然后定义一些点:
/// object collection
var myPolygons = [];
/// add polygons to it
myPolygons.push( new Polygon([[10,10], [30,30], [70,70]], 'black') );
myPolygons.push( new Polygon([[50,40], [70,80], [30,30]], 'red') );
渲染多边形
然后渲染多边形:
for(var i = 0, p, points; p = myPolygons[i]; i++) {
points = p.points;
ctx.beginPath();
ctx.moveTo(points[0][0], points[0][1]);
for(var t = 1; t < points.length; t++) {
ctx.lineTo(points[t][0], points[t][1]);
}
ctx.closePath();
ctx.fillStyle = p.color;
ctx.fill();
}
检查点是否在路径中
x, y
然后在单击时根据位置检查命中。
如您所见,该函数与渲染函数几乎相同(当然您可以将它们重构为单个函数),但这实际上并没有绘制任何东西,只是重新构建了检查路径。
for(var i = 0, p, points; p = myPolygons[i]; i++) {
points = p.points;
ctx.beginPath();
ctx.moveTo(points[0][0], points[0][1]);
for(var t = 1; t < points.length; t++) {
ctx.lineTo(points[t][0], points[t][1]);
}
ctx.closePath();
/// instead of drawing anything, we check:
if (ctx.isPointInPath(x, y) === true) {
alert('Hit: ' + p.color);
return;
}
}
结论
通常这会比迭代位图数组更快(这也是一个非常好的解决方案)。这主要是因为检查是在编译代码内部完成的。
将来,我们将可以自己构建 Path 对象,这样我们就可以简单地传递一个已经保存了所有路径信息的 Path 对象,而不是重新构建它,这意味着更快的速度。
于 2013-04-08T09:04:30.317 回答