package.interaction.Pointer.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ol Show documentation
Show all versions of ol Show documentation
OpenLayers mapping library
The newest version!
/**
* @module ol/interaction/Pointer
*/
import Interaction from './Interaction.js';
import MapBrowserEventType from '../MapBrowserEventType.js';
/**
* @typedef {Object} Options
* @property {function(import("../MapBrowserEvent.js").default):boolean} [handleDownEvent]
* Function handling "down" events. If the function returns `true` then a drag
* sequence is started.
* @property {function(import("../MapBrowserEvent.js").default):void} [handleDragEvent]
* Function handling "drag" events. This function is called on "move" events
* during a drag sequence.
* @property {function(import("../MapBrowserEvent.js").default):boolean} [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.
* @property {function(import("../MapBrowserEvent.js").default):void} [handleMoveEvent]
* Function handling "move" events. This function is called on "move" events.
* This functions is also called during a drag sequence, so during a drag
* sequence both the `handleDragEvent` function and this function are called.
* If `handleDownEvent` is defined and it returns true this function will not
* be called during a drag sequence.
* @property {function(import("../MapBrowserEvent.js").default):boolean} [handleUpEvent]
* Function handling "up" events. If the function returns `false` then the
* current drag sequence is stopped.
* @property {function(boolean):boolean} [stopDown]
* Should the down event be propagated to other interactions, or should be
* stopped?
*/
/**
* @classdesc
* Base class that calls user-defined functions on `down`, `move` and `up`
* events. This class also manages "drag sequences".
*
* When the `handleDownEvent` user function returns `true` a drag sequence is
* started. During a drag sequence the `handleDragEvent` user function is
* called on `move` events. The drag sequence ends when the `handleUpEvent`
* user function is called and returns `false`.
* @api
*/
class PointerInteraction extends Interaction {
/**
* @param {Options} [options] Options.
*/
constructor(options) {
options = options ? options : {};
super(
/** @type {import("./Interaction.js").InteractionOptions} */ (options),
);
if (options.handleDownEvent) {
this.handleDownEvent = options.handleDownEvent;
}
if (options.handleDragEvent) {
this.handleDragEvent = options.handleDragEvent;
}
if (options.handleMoveEvent) {
this.handleMoveEvent = options.handleMoveEvent;
}
if (options.handleUpEvent) {
this.handleUpEvent = options.handleUpEvent;
}
if (options.stopDown) {
this.stopDown = options.stopDown;
}
/**
* @type {boolean}
* @protected
*/
this.handlingDownUpSequence = false;
/**
* @type {Array}
* @protected
*/
this.targetPointers = [];
}
/**
* Returns the current number of pointers involved in the interaction,
* e.g. `2` when two fingers are used.
* @return {number} The number of pointers.
* @api
*/
getPointerCount() {
return this.targetPointers.length;
}
/**
* Handle pointer down events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @return {boolean} If the event was consumed.
* @protected
*/
handleDownEvent(mapBrowserEvent) {
return false;
}
/**
* Handle pointer drag events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @protected
*/
handleDragEvent(mapBrowserEvent) {}
/**
* Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} and may call into
* other functions, if event sequences like e.g. 'drag' or 'down-up' etc. are
* detected.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
* @return {boolean} `false` to stop event propagation.
* @api
* @override
*/
handleEvent(mapBrowserEvent) {
if (!mapBrowserEvent.originalEvent) {
return true;
}
let stopEvent = false;
this.updateTrackedPointers_(mapBrowserEvent);
if (this.handlingDownUpSequence) {
if (mapBrowserEvent.type == MapBrowserEventType.POINTERDRAG) {
this.handleDragEvent(mapBrowserEvent);
// prevent page scrolling during dragging
mapBrowserEvent.originalEvent.preventDefault();
} else if (mapBrowserEvent.type == MapBrowserEventType.POINTERUP) {
const handledUp = this.handleUpEvent(mapBrowserEvent);
this.handlingDownUpSequence =
handledUp && this.targetPointers.length > 0;
}
} else {
if (mapBrowserEvent.type == MapBrowserEventType.POINTERDOWN) {
const handled = this.handleDownEvent(mapBrowserEvent);
this.handlingDownUpSequence = handled;
stopEvent = this.stopDown(handled);
} else if (mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE) {
this.handleMoveEvent(mapBrowserEvent);
}
}
return !stopEvent;
}
/**
* Handle pointer move events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @protected
*/
handleMoveEvent(mapBrowserEvent) {}
/**
* Handle pointer up events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @return {boolean} If the event was consumed.
* @protected
*/
handleUpEvent(mapBrowserEvent) {
return false;
}
/**
* This function is used to determine if "down" events should be propagated
* to other interactions or should be stopped.
* @param {boolean} handled Was the event handled by the interaction?
* @return {boolean} Should the `down` event be stopped?
*/
stopDown(handled) {
return handled;
}
/**
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @private
*/
updateTrackedPointers_(mapBrowserEvent) {
if (mapBrowserEvent.activePointers) {
this.targetPointers = mapBrowserEvent.activePointers;
}
}
}
/**
* @param {Array} pointerEvents List of events.
* @return {{clientX: number, clientY: number}} Centroid pixel.
*/
export function centroid(pointerEvents) {
const length = pointerEvents.length;
let clientX = 0;
let clientY = 0;
for (let i = 0; i < length; i++) {
clientX += pointerEvents[i].clientX;
clientY += pointerEvents[i].clientY;
}
return {clientX: clientX / length, clientY: clientY / length};
}
export default PointerInteraction;