0

我正在开发一个 HTML5 画布应用程序。我现在能够找到我在画布上单击的任何点的坐标和十六进制值。如果假设我正在单击一个具有填充多边形的区域(并且我知道多边形的颜色)。有什么方法或算法可以返回绘制多边形的封闭坐标?

4

1 回答 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 回答