diff --git a/examples/select-features.html b/examples/select-features.html index 55481d0372..697b309a39 100644 --- a/examples/select-features.html +++ b/examples/select-features.html @@ -18,5 +18,13 @@ tags: "select, vector" -  0 selected features +  0 selected features +
+ + + diff --git a/examples/select-features.js b/examples/select-features.js index 8d68284e2c..5d0a658f7a 100644 --- a/examples/select-features.js +++ b/examples/select-features.js @@ -31,23 +31,28 @@ var map = new ol.Map({ var select = null; // ref to currently selected interaction // select interaction working on "singleclick" -var selectSingleClick = new ol.interaction.Select(); +var selectSingleClick = new ol.interaction.Select({ + multi: true // multi is used in this example if hitTolerance > 0 +}); // select interaction working on "click" var selectClick = new ol.interaction.Select({ - condition: ol.events.condition.click + condition: ol.events.condition.click, + multi: true }); // select interaction working on "pointermove" var selectPointerMove = new ol.interaction.Select({ - condition: ol.events.condition.pointerMove + condition: ol.events.condition.pointerMove, + multi: true }); var selectAltClick = new ol.interaction.Select({ condition: function(mapBrowserEvent) { return ol.events.condition.click(mapBrowserEvent) && ol.events.condition.altKeyOnly(mapBrowserEvent); - } + }, + multi: true }); var selectElement = document.getElementById('type'); @@ -85,3 +90,27 @@ var changeInteraction = function() { */ selectElement.onchange = changeInteraction; changeInteraction(); + +var selectHitToleranceElement = document.getElementById('hitTolerance'); +var circleCanvas = document.getElementById('circle'); + +var changeHitTolerance = function() { + var value = parseInt(selectHitToleranceElement.value, 10); + selectSingleClick.setHitTolerance(value); + selectClick.setHitTolerance(value); + selectPointerMove.setHitTolerance(value); + selectAltClick.setHitTolerance(value); + + var size = 2 * value + 2; + circleCanvas.width = size; + circleCanvas.height = size; + var ctx = circleCanvas.getContext('2d'); + ctx.clearRect(0, 0, size, size); + ctx.beginPath(); + ctx.arc(value + 1, value + 1, value + 0.5, 0, 2 * Math.PI); + ctx.fill(); + ctx.stroke(); +}; + +selectHitToleranceElement.onchange = changeHitTolerance; +changeHitTolerance(); diff --git a/externs/olx.js b/externs/olx.js index dd7bac146e..d8317a98c0 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -3212,7 +3212,8 @@ olx.interaction.PointerOptions.prototype.handleUpEvent; * multi: (boolean|undefined), * features: (ol.Collection.|undefined), * filter: (ol.SelectFilterFunction|undefined), - * wrapX: (boolean|undefined)}} + * wrapX: (boolean|undefined), + * hitTolerance: (number|undefined)}} */ olx.interaction.SelectOptions; @@ -3326,6 +3327,16 @@ olx.interaction.SelectOptions.prototype.filter; olx.interaction.SelectOptions.prototype.wrapX; +/** + * Hit-detection tolerance. Pixels inside the radius around the given position + * will be checked for features. This only works for the canvas renderer and + * not for WebGL. + * @type {number|undefined} + * @api + */ +olx.interaction.SelectOptions.prototype.hitTolerance; + + /** * Options for snap * @typedef {{ diff --git a/src/ol/interaction/select.js b/src/ol/interaction/select.js index d6b233cab6..dbcd376efc 100644 --- a/src/ol/interaction/select.js +++ b/src/ol/interaction/select.js @@ -82,6 +82,8 @@ ol.interaction.Select = function(opt_options) { this.filter_ = options.filter ? options.filter : ol.functions.TRUE; + this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0; + var featureOverlay = new ol.layer.Vector({ source: new ol.source.Vector({ useSpatialIndex: false, @@ -160,6 +162,16 @@ ol.interaction.Select.prototype.getFeatures = function() { }; +/** + * Returns the Hit-detection tolerance. + * @returns {number} Hit tolerance. + * @api + */ +ol.interaction.Select.prototype.getHitTolerance = function() { + return this.hitTolerance_; +}; + + /** * Returns the associated {@link ol.layer.Vector vectorlayer} of * the (last) selected feature. Note that this will not work with any @@ -212,7 +224,10 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { this.addFeatureLayerAssociation_(feature, layer); return !this.multi_; } - }, this, {layerFilter: this.layerFilter_}); + }, this, { + layerFilter: this.layerFilter_, + hitTolerance: this.hitTolerance_ + }); var i; for (i = features.getLength() - 1; i >= 0; --i) { var feature = features.item(i); @@ -249,7 +264,10 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { } return !this.multi_; } - }, this, {layerFilter: this.layerFilter_}); + }, this, { + layerFilter: this.layerFilter_, + hitTolerance: this.hitTolerance_ + }); var j; for (j = deselected.length - 1; j >= 0; --j) { features.remove(deselected[j]); @@ -265,6 +283,18 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { }; +/** + * Hit-detection tolerance. Pixels inside the radius around the given position + * will be checked for features. This only works for the canvas renderer and + * not for WebGL. + * @param {number} hitTolerance Hit tolerance. + * @api + */ +ol.interaction.Select.prototype.setHitTolerance = function(hitTolerance) { + this.hitTolerance_ = hitTolerance; +}; + + /** * Remove the interaction from its current map, if any, and attach it to a new * map, if any. Pass `null` to just remove the interaction from the current map.