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:
Arjen Kopinga
2012-03-06 11:50:15 +01:00
parent 81b2b524ec
commit a836224a14
2 changed files with 45 additions and 5 deletions

View File

@@ -322,6 +322,11 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
this.canvas.lineCap = "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.
if (style.graphicName in this.cachedSymbolBounds) {
symbolBounds = this.cachedSymbolBounds[style.graphicName];
@@ -393,9 +398,7 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
if (style.stroke !== false) {
this.setCanvasStyle("stroke", style);
this.canvas.beginPath();
for (i=0; i<symbol.length; i=i+2) {
x = symbol[i];
y = symbol[i+1];
@@ -404,6 +407,21 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
}
this.canvas.closePath();
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;
@@ -465,7 +483,7 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
* featureId - {String} The feature id.
* symbolizer - {<OpenLayers.Symbolizer>} The symbolizer.
*/
setHitContextStyle: function(type, featureId, symbolizer) {
setHitContextStyle: function(type, featureId, symbolizer, strokeScaling) {
var hex = this.featureIdToHex(featureId);
if (type == "fill") {
this.hitContext.globalAlpha = 1.0;
@@ -473,8 +491,13 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
} else if (type == "stroke") {
this.hitContext.globalAlpha = 1.0;
this.hitContext.strokeStyle = hex;
// bump up stroke width to deal with antialiasing
this.hitContext.lineWidth = symbolizer.strokeWidth + 2;
// bump up stroke width to deal with antialiasing. If strokeScaling is defined, we're rendering a symbol
// 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 {
this.hitContext.globalAlpha = 0;
this.hitContext.lineWidth = 1;

View File

@@ -304,6 +304,17 @@
),
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))")
),
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: "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) {