added hit detection for symbol edges to canvas renderer with unit tests
Added unit tests for hit detection on invisible canvas layer simplified unit test for hit detection on invisible canvas
This commit is contained in:
@@ -322,6 +322,11 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
|
|||||||
this.canvas.lineCap = "round";
|
this.canvas.lineCap = "round";
|
||||||
this.canvas.lineJoin = "round";
|
this.canvas.lineJoin = "round";
|
||||||
|
|
||||||
|
if (this.hitDetection) {
|
||||||
|
this.hitContext.lineCap = "round";
|
||||||
|
this.hitContext.lineJoin = "round";
|
||||||
|
}
|
||||||
|
|
||||||
// Scale and rotate symbols, using precalculated bounds whenever possible.
|
// Scale and rotate symbols, using precalculated bounds whenever possible.
|
||||||
if (style.graphicName in this.cachedSymbolBounds) {
|
if (style.graphicName in this.cachedSymbolBounds) {
|
||||||
symbolBounds = this.cachedSymbolBounds[style.graphicName];
|
symbolBounds = this.cachedSymbolBounds[style.graphicName];
|
||||||
@@ -393,9 +398,7 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
|
|||||||
|
|
||||||
if (style.stroke !== false) {
|
if (style.stroke !== false) {
|
||||||
this.setCanvasStyle("stroke", style);
|
this.setCanvasStyle("stroke", style);
|
||||||
|
|
||||||
this.canvas.beginPath();
|
this.canvas.beginPath();
|
||||||
|
|
||||||
for (i=0; i<symbol.length; i=i+2) {
|
for (i=0; i<symbol.length; i=i+2) {
|
||||||
x = symbol[i];
|
x = symbol[i];
|
||||||
y = symbol[i+1];
|
y = symbol[i+1];
|
||||||
@@ -404,6 +407,21 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
|
|||||||
}
|
}
|
||||||
this.canvas.closePath();
|
this.canvas.closePath();
|
||||||
this.canvas.stroke();
|
this.canvas.stroke();
|
||||||
|
|
||||||
|
|
||||||
|
if (this.hitDetection) {
|
||||||
|
this.setHitContextStyle("stroke", featureId, style, scaling);
|
||||||
|
this.hitContext.beginPath();
|
||||||
|
for (i=0; i<symbol.length; i=i+2) {
|
||||||
|
x = symbol[i];
|
||||||
|
y = symbol[i+1];
|
||||||
|
if (i == 0) this.hitContext.moveTo(x,y);
|
||||||
|
this.hitContext.lineTo(x,y);
|
||||||
|
}
|
||||||
|
this.hitContext.closePath();
|
||||||
|
this.hitContext.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
style.strokeWidth = unscaledStrokeWidth;
|
style.strokeWidth = unscaledStrokeWidth;
|
||||||
@@ -465,7 +483,7 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
|
|||||||
* featureId - {String} The feature id.
|
* featureId - {String} The feature id.
|
||||||
* symbolizer - {<OpenLayers.Symbolizer>} The symbolizer.
|
* symbolizer - {<OpenLayers.Symbolizer>} The symbolizer.
|
||||||
*/
|
*/
|
||||||
setHitContextStyle: function(type, featureId, symbolizer) {
|
setHitContextStyle: function(type, featureId, symbolizer, strokeScaling) {
|
||||||
var hex = this.featureIdToHex(featureId);
|
var hex = this.featureIdToHex(featureId);
|
||||||
if (type == "fill") {
|
if (type == "fill") {
|
||||||
this.hitContext.globalAlpha = 1.0;
|
this.hitContext.globalAlpha = 1.0;
|
||||||
@@ -473,8 +491,13 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
|
|||||||
} else if (type == "stroke") {
|
} else if (type == "stroke") {
|
||||||
this.hitContext.globalAlpha = 1.0;
|
this.hitContext.globalAlpha = 1.0;
|
||||||
this.hitContext.strokeStyle = hex;
|
this.hitContext.strokeStyle = hex;
|
||||||
// bump up stroke width to deal with antialiasing
|
// bump up stroke width to deal with antialiasing. If strokeScaling is defined, we're rendering a symbol
|
||||||
this.hitContext.lineWidth = symbolizer.strokeWidth + 2;
|
// on a transformed canvas, so the antialias width bump has to scale as well.
|
||||||
|
if (typeof strokeScaling === "undefined") {
|
||||||
|
this.hitContext.lineWidth = symbolizer.strokeWidth + 2;
|
||||||
|
} else {
|
||||||
|
if (!isNaN(strokeScaling)) { this.hitContext.lineWidth = symbolizer.strokeWidth + 2.0 / strokeScaling; }
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.hitContext.globalAlpha = 0;
|
this.hitContext.globalAlpha = 0;
|
||||||
this.hitContext.lineWidth = 1;
|
this.hitContext.lineWidth = 1;
|
||||||
|
|||||||
@@ -304,6 +304,17 @@
|
|||||||
),
|
),
|
||||||
new OpenLayers.Feature.Vector(
|
new OpenLayers.Feature.Vector(
|
||||||
OpenLayers.Geometry.fromWKT("POLYGON((100 -25, 150 -25, 150 25, 100 25, 100 -25), (120 -5, 130 -5, 130 5, 120 5, 120 -5))")
|
OpenLayers.Geometry.fromWKT("POLYGON((100 -25, 150 -25, 150 25, 100 25, 100 -25), (120 -5, 130 -5, 130 5, 120 5, 120 -5))")
|
||||||
|
),
|
||||||
|
new OpenLayers.Feature.Vector(
|
||||||
|
new OpenLayers.Geometry.Point(80, 0), {}, {
|
||||||
|
graphicName: "square",
|
||||||
|
pointRadius: 5,
|
||||||
|
strokeWidth: 3,
|
||||||
|
fillColor: "red",
|
||||||
|
fillOpacity: 0.5,
|
||||||
|
strokeColor: "blue",
|
||||||
|
strokeOpacity: 0.75
|
||||||
|
}
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -327,6 +338,12 @@
|
|||||||
msg: "inside polygon hole", x: 125, y: 0, id: null
|
msg: "inside polygon hole", x: 125, y: 0, id: null
|
||||||
}, {
|
}, {
|
||||||
msg: "outside polygon", x: 155, y: 0, id: null
|
msg: "outside polygon", x: 155, y: 0, id: null
|
||||||
|
}, {
|
||||||
|
msg: "inside symbol", x: 80, y: 0, id: layer.features[3].id
|
||||||
|
}, {
|
||||||
|
msg: "outside symbol interior, inside symbol edge", x: 86, y: 6, id: layer.features[3].id
|
||||||
|
}, {
|
||||||
|
msg: "outside symbol", x: 90, y: 0, id: null
|
||||||
}];
|
}];
|
||||||
|
|
||||||
function px(x, y) {
|
function px(x, y) {
|
||||||
|
|||||||
Reference in New Issue
Block a user