質問

Derived from this: How to tackle diagonally stacked, rounded image background element hovers?

I made imagemap areas and transformed them for my case, but, now there is a problem with point in polygon hit detection.

It appears that only the bottom right quadrant is always correct, but, only if looking outside the ring - inside the detection might be still be incorrect. Other quadrants, outside the ring, occasionally report a positive hit where it should be false.

Fiddle: http://jsfiddle.net/psycketom/9J4dx/1/

The red lines are drawn from the polygon that's generated from data-map.

The blue line represents the polygon we're currently checking.

The point in polygon function comes from: https://github.com/substack/point-in-polygon

var pointInPolygon = function(point, vs)
{
    // ray-casting algorithm based on
    // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html

    var x = point[0], y = point[1];

    var inside = false;
    for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
        var xi = vs[i][0], yi = vs[i][1];
        var xj = vs[j][0], yj = vs[j][1];

        var intersect = ((yi > y) != (yj > y))
            && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
        if (intersect) inside = !inside;
    }

    return inside;
};

I cannot seem to understand what's the problem here.

役に立ちましたか?

解決

Your mapToPolygon function doesn't convert the parsed points from string to number. Because of this, the pointInPolygon function ends up comparing the strings of the coordinates, not the actual coordinates. Using a parseInt on line 31 of the fiddle fixes the problem.

他のヒント

Create an off-screen canvas and use the context's .isPointInPath(x, y) function.

Loop through all of your polygons (in your example you would loop through them in reverse because you have smallest last. The smallest would be the highest level / greatest z-index).

On you get a hit (isPointInPath returns true) stop.

Something like...

var offcanvas = document.createElement("canvas");
...
var x = e.pageX - $ages.offset().left;
var y = e.pageY - $ages.offset().top;
revlayers.each(function() {
    var $elm = $(this);
    var poly = $elm.data("polygon");
    var ctx = offcanvas.getContext("2d");
    if(poly.length > 0) {
        ctx.beginPath();
        ctx.moveTo(poly[0][0], poly[0][1]);
        for(var i=1; i<poly.length; i++) {
            ctx.lineTo(poly[i][0], poly[i][1]);
        }
        if(ctx.isPointInPath(x, y)) {
            hit.text($elm.attr("href"));
            return false; // end the .each() loop
        }
    }
})
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top