198 lines
6.2 KiB
JavaScript
198 lines
6.2 KiB
JavaScript
import ol_interaction_Interaction from 'ol/interaction/Interaction.js'
|
|
import ol_ext_element from '../util/element.js';
|
|
|
|
/** Interaction hover do to something when hovering a feature
|
|
* @constructor
|
|
* @extends {ol_interaction_Interaction}
|
|
* @fires hover, enter, leave
|
|
* @param {olx.interaction.HoverOptions}
|
|
* @param { string | undefined } options.cursor css cursor propertie or a function that gets a feature, default: none
|
|
* @param {function | undefined} options.featureFilter filter a function with two arguments, the feature and the layer of the feature. Return true to select the feature
|
|
* @param {function | undefined} options.layerFilter filter a function with one argument, the layer to test. Return true to test the layer
|
|
* @param {Array<ol.layer> | undefined} options.layers a set of layers to test
|
|
* @param {number | undefined} options.hitTolerance Hit-detection tolerance in pixels.
|
|
* @param { function | undefined } options.handleEvent Method called by the map to notify the interaction that a browser event was dispatched to the map. The function may return false to prevent the propagation of the event to other interactions in the map's interactions chain.
|
|
*/
|
|
var ol_interaction_Hover = class olinteractionHover extends ol_interaction_Interaction {
|
|
constructor(options) {
|
|
if (!options)
|
|
options = options || {};
|
|
|
|
var dragging = false;
|
|
|
|
super({
|
|
handleEvent: function (e) {
|
|
if (!self.getActive())
|
|
return true;
|
|
switch (e.type) {
|
|
case 'pointerdrag': {
|
|
dragging = true;
|
|
break;
|
|
}
|
|
case 'pointerup': {
|
|
dragging = false;
|
|
break;
|
|
}
|
|
case 'pointermove': {
|
|
if (!dragging) {
|
|
self.handleMove_(e);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (options.handleEvent)
|
|
return options.handleEvent(e);
|
|
return true;
|
|
}
|
|
});
|
|
var self = this;
|
|
|
|
this.setLayerFilter(options.layerFilter);
|
|
if (options.layers && options.layers.length) {
|
|
this.setLayerFilter(function (l) {
|
|
return (options.layers.indexOf(l) >= 0);
|
|
});
|
|
}
|
|
this.setFeatureFilter(options.featureFilter);
|
|
this.set('hitTolerance', options.hitTolerance);
|
|
this.setCursor(options.cursor);
|
|
}
|
|
/**
|
|
* 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.
|
|
* @param {ol.Map} map Map.
|
|
* @api stable
|
|
*/
|
|
setMap(map) {
|
|
if (this.previousCursor_ !== undefined && this.getMap()) {
|
|
ol_ext_element.setCursor(this.getMap(), this.previousCursor_);
|
|
this.previousCursor_ = undefined;
|
|
}
|
|
super.setMap(map);
|
|
}
|
|
/** Activate / deactivate interaction
|
|
* @param {boolean} b
|
|
*/
|
|
setActive(b) {
|
|
super.setActive(b);
|
|
if (this.cursor_ && this.getMap() && this.getMap().getTargetElement()) {
|
|
if (this.previousCursor_ !== undefined) {
|
|
ol_ext_element.setCursor(this.getMap(), this.previousCursor_);
|
|
this.previousCursor_ = undefined;
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Set cursor on hover
|
|
* @param { string } cursor css cursor propertie or a function that gets a feature, default: none
|
|
* @api stable
|
|
*/
|
|
setCursor(cursor) {
|
|
if (!cursor && this.previousCursor_ !== undefined && this.getMap()) {
|
|
ol_ext_element.setCursor(this.getMap(), this.previousCursor_);
|
|
this.previousCursor_ = undefined;
|
|
}
|
|
this.cursor_ = cursor;
|
|
}
|
|
/** Feature filter to get only one feature
|
|
* @param {function} filter a function with two arguments, the feature and the layer of the feature. Return true to select the feature
|
|
*/
|
|
setFeatureFilter(filter) {
|
|
if (typeof (filter) == 'function')
|
|
this.featureFilter_ = filter;
|
|
else
|
|
this.featureFilter_ = function () { return true; };
|
|
}
|
|
/** Feature filter to get only one feature
|
|
* @param {function} filter a function with one argument, the layer to test. Return true to test the layer
|
|
*/
|
|
setLayerFilter(filter) {
|
|
if (typeof (filter) == 'function')
|
|
this.layerFilter_ = filter;
|
|
else
|
|
this.layerFilter_ = function () { return true; };
|
|
}
|
|
/** Get features whenmove
|
|
* @param {ol.event} e "move" event
|
|
*/
|
|
handleMove_(e) {
|
|
var map = this.getMap();
|
|
if (map) {
|
|
//var b = map.hasFeatureAtPixel(e.pixel);
|
|
var feature, layer;
|
|
var self = this;
|
|
var b = map.forEachFeatureAtPixel(
|
|
e.pixel,
|
|
function (f, l) {
|
|
if (self.featureFilter_.call(null, f, l)) {
|
|
feature = f;
|
|
layer = l;
|
|
return true;
|
|
} else {
|
|
feature = layer = null;
|
|
return false;
|
|
}
|
|
}, {
|
|
hitTolerance: this.get('hitTolerance'),
|
|
layerFilter: self.layerFilter_
|
|
}
|
|
);
|
|
|
|
if (b)
|
|
this.dispatchEvent({
|
|
type: 'hover',
|
|
feature: feature,
|
|
layer: layer,
|
|
coordinate: e.coordinate,
|
|
pixel: e.pixel,
|
|
map: e.map,
|
|
originalEvent: e.originalEvent,
|
|
dragging: e.dragging
|
|
});
|
|
|
|
if (this.feature_ === feature && this.layer_ === layer) {
|
|
/* ok */
|
|
} else {
|
|
this.feature_ = feature;
|
|
this.layer_ = layer;
|
|
if (feature) {
|
|
this.dispatchEvent({
|
|
type: 'enter',
|
|
feature: feature,
|
|
layer: layer,
|
|
coordinate: e.coordinate,
|
|
pixel: e.pixel,
|
|
map: e.map,
|
|
originalEvent: e.originalEvent,
|
|
dragging: e.dragging
|
|
});
|
|
} else {
|
|
this.dispatchEvent({
|
|
type: 'leave',
|
|
coordinate: e.coordinate,
|
|
pixel: e.pixel,
|
|
map: e.map,
|
|
originalEvent: e.originalEvent,
|
|
dragging: e.dragging
|
|
});
|
|
}
|
|
}
|
|
|
|
if (this.cursor_) {
|
|
var style = map.getTargetElement().style;
|
|
if (b) {
|
|
if (style.cursor != this.cursor_) {
|
|
this.previousCursor_ = style.cursor;
|
|
ol_ext_element.setCursor(map, this.cursor_);
|
|
}
|
|
} else if (this.previousCursor_ !== undefined) {
|
|
ol_ext_element.setCursor(map, this.previousCursor_);
|
|
this.previousCursor_ = undefined;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export default ol_interaction_Hover
|