From a836224a144fbd136e5b2dac65bc3e5d7809b818 Mon Sep 17 00:00:00 2001 From: Arjen Kopinga Date: Tue, 6 Mar 2012 11:50:15 +0100 Subject: [PATCH 1/2] 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 --- lib/OpenLayers/Renderer/Canvas.js | 33 ++++++++++++++++++++++++++----- tests/Renderer/Canvas.html | 17 ++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/lib/OpenLayers/Renderer/Canvas.js b/lib/OpenLayers/Renderer/Canvas.js index 74ae40b768..b8e4a79191 100644 --- a/lib/OpenLayers/Renderer/Canvas.js +++ b/lib/OpenLayers/Renderer/Canvas.js @@ -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} 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; diff --git a/tests/Renderer/Canvas.html b/tests/Renderer/Canvas.html index 303b56732d..5cbcc0e8fc 100644 --- a/tests/Renderer/Canvas.html +++ b/tests/Renderer/Canvas.html @@ -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) { From 677659df96a82c5d0041aed41ad642cb84ec54b5 Mon Sep 17 00:00:00 2001 From: Arjen Kopinga Date: Tue, 6 Mar 2012 15:27:26 +0100 Subject: [PATCH 2/2] broadening stroke width in symbol edge hit detection test to lessen sensitivity to browser antialiasing differences --- tests/Renderer/Canvas.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Renderer/Canvas.html b/tests/Renderer/Canvas.html index 5cbcc0e8fc..a1343bba11 100644 --- a/tests/Renderer/Canvas.html +++ b/tests/Renderer/Canvas.html @@ -308,8 +308,8 @@ new OpenLayers.Feature.Vector( new OpenLayers.Geometry.Point(80, 0), {}, { graphicName: "square", - pointRadius: 5, - strokeWidth: 3, + pointRadius: 8, + strokeWidth: 4, fillColor: "red", fillOpacity: 0.5, strokeColor: "blue", @@ -341,9 +341,9 @@ }, { 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 interior, inside symbol edge", x: 90, y: 8, id: layer.features[3].id }, { - msg: "outside symbol", x: 90, y: 0, id: null + msg: "outside symbol", x: 94, y: 0, id: null }]; function px(x, y) {