Merge pull request #8762 from schmidtk/ts-pointer-interaction-this

Fix type errors from interaction event handlers
This commit is contained in:
Andreas Hocevar
2018-10-03 15:48:54 +02:00
committed by GitHub
18 changed files with 1348 additions and 1364 deletions
+29 -43
View File
@@ -115,11 +115,7 @@ class DragBox extends PointerInteraction {
*/ */
constructor(opt_options) { constructor(opt_options) {
super({ super();
handleDownEvent: handleDownEvent,
handleDragEvent: handleDragEvent,
handleUpEvent: handleUpEvent
});
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
@@ -159,7 +155,22 @@ class DragBox extends PointerInteraction {
* @type {EndCondition} * @type {EndCondition}
*/ */
this.boxEndCondition_ = options.boxEndCondition ? this.boxEndCondition_ = options.boxEndCondition ?
options.boxEndCondition : defaultBoxEndCondition; options.boxEndCondition : this.defaultBoxEndCondition;
}
/**
* The default condition for determining whether the boxend event
* should fire.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent The originating MapBrowserEvent
* leading to the box end.
* @param {import("../pixel.js").Pixel} startPixel The starting pixel of the box.
* @param {import("../pixel.js").Pixel} endPixel The end pixel of the box.
* @return {boolean} Whether or not the boxend condition should be fired.
*/
defaultBoxEndCondition(mapBrowserEvent, startPixel, endPixel) {
const width = endPixel[0] - startPixel[0];
const height = endPixel[1] - startPixel[1];
return width * width + height * height >= this.minArea_;
} }
/** /**
@@ -170,31 +181,11 @@ class DragBox extends PointerInteraction {
getGeometry() { getGeometry() {
return this.box_.getGeometry(); return this.box_.getGeometry();
} }
}
/**
/** * @inheritDoc
* The default condition for determining whether the boxend event
* should fire.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent The originating MapBrowserEvent
* leading to the box end.
* @param {import("../pixel.js").Pixel} startPixel The starting pixel of the box.
* @param {import("../pixel.js").Pixel} endPixel The end pixel of the box.
* @return {boolean} Whether or not the boxend condition should be fired.
* @this {DragBox}
*/ */
function defaultBoxEndCondition(mapBrowserEvent, startPixel, endPixel) { handleDragEvent(mapBrowserEvent) {
const width = endPixel[0] - startPixel[0];
const height = endPixel[1] - startPixel[1];
return width * width + height * height >= this.minArea_;
}
/**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @this {DragBox}
*/
function handleDragEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) { if (!mouseOnly(mapBrowserEvent)) {
return; return;
} }
@@ -203,15 +194,12 @@ function handleDragEvent(mapBrowserEvent) {
this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXDRAG, this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXDRAG,
mapBrowserEvent.coordinate, mapBrowserEvent)); mapBrowserEvent.coordinate, mapBrowserEvent));
} }
/**
/** * @inheritDoc
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Stop drag sequence?
* @this {DragBox}
*/ */
function handleUpEvent(mapBrowserEvent) { handleUpEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) { if (!mouseOnly(mapBrowserEvent)) {
return true; return true;
} }
@@ -224,15 +212,12 @@ function handleUpEvent(mapBrowserEvent) {
mapBrowserEvent.coordinate, mapBrowserEvent)); mapBrowserEvent.coordinate, mapBrowserEvent));
} }
return false; return false;
} }
/**
/** * @inheritDoc
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Start drag sequence?
* @this {DragBox}
*/ */
function handleDownEvent(mapBrowserEvent) { handleDownEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) { if (!mouseOnly(mapBrowserEvent)) {
return false; return false;
} }
@@ -248,6 +233,7 @@ function handleDownEvent(mapBrowserEvent) {
} else { } else {
return false; return false;
} }
}
} }
+12 -25
View File
@@ -30,9 +30,6 @@ class DragPan extends PointerInteraction {
constructor(opt_options) { constructor(opt_options) {
super({ super({
handleDownEvent: handleDownEvent,
handleDragEvent: handleDragEvent,
handleUpEvent: handleUpEvent,
stopDown: FALSE stopDown: FALSE
}); });
@@ -73,14 +70,10 @@ class DragPan extends PointerInteraction {
} }
} /**
* @inheritDoc
/**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @this {DragPan}
*/ */
function handleDragEvent(mapBrowserEvent) { handleDragEvent(mapBrowserEvent) {
if (!this.panning_) { if (!this.panning_) {
this.panning_ = true; this.panning_ = true;
this.getMap().getView().setHint(ViewHint.INTERACTING, 1); this.getMap().getView().setHint(ViewHint.INTERACTING, 1);
@@ -110,15 +103,12 @@ function handleDragEvent(mapBrowserEvent) {
} }
this.lastCentroid = centroid; this.lastCentroid = centroid;
this.lastPointersCount_ = targetPointers.length; this.lastPointersCount_ = targetPointers.length;
} }
/**
/** * @inheritDoc
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Stop drag sequence?
* @this {DragPan}
*/ */
function handleUpEvent(mapBrowserEvent) { handleUpEvent(mapBrowserEvent) {
const map = mapBrowserEvent.map; const map = mapBrowserEvent.map;
const view = map.getView(); const view = map.getView();
if (this.targetPointers.length === 0) { if (this.targetPointers.length === 0) {
@@ -151,15 +141,12 @@ function handleUpEvent(mapBrowserEvent) {
this.lastCentroid = null; this.lastCentroid = null;
return true; return true;
} }
} }
/**
/** * @inheritDoc
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Start drag sequence?
* @this {DragPan}
*/ */
function handleDownEvent(mapBrowserEvent) { handleDownEvent(mapBrowserEvent) {
if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) { if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {
const map = mapBrowserEvent.map; const map = mapBrowserEvent.map;
const view = map.getView(); const view = map.getView();
@@ -178,7 +165,7 @@ function handleDownEvent(mapBrowserEvent) {
} else { } else {
return false; return false;
} }
}
} }
export default DragPan; export default DragPan;
+12 -22
View File
@@ -38,9 +38,6 @@ class DragRotate extends PointerInteraction {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super({ super({
handleDownEvent: handleDownEvent,
handleDragEvent: handleDragEvent,
handleUpEvent: handleUpEvent,
stopDown: FALSE stopDown: FALSE
}); });
@@ -64,14 +61,10 @@ class DragRotate extends PointerInteraction {
} }
} /**
* @inheritDoc
/**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @this {DragRotate}
*/ */
function handleDragEvent(mapBrowserEvent) { handleDragEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) { if (!mouseOnly(mapBrowserEvent)) {
return; return;
} }
@@ -91,15 +84,13 @@ function handleDragEvent(mapBrowserEvent) {
rotateWithoutConstraints(view, rotation - delta); rotateWithoutConstraints(view, rotation - delta);
} }
this.lastAngle_ = theta; this.lastAngle_ = theta;
} }
/** /**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event. * @inheritDoc
* @return {boolean} Stop drag sequence?
* @this {DragRotate}
*/ */
function handleUpEvent(mapBrowserEvent) { handleUpEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) { if (!mouseOnly(mapBrowserEvent)) {
return true; return true;
} }
@@ -110,15 +101,13 @@ function handleUpEvent(mapBrowserEvent) {
const rotation = view.getRotation(); const rotation = view.getRotation();
rotate(view, rotation, undefined, this.duration_); rotate(view, rotation, undefined, this.duration_);
return false; return false;
} }
/** /**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event. * @inheritDoc
* @return {boolean} Start drag sequence?
* @this {DragRotate}
*/ */
function handleDownEvent(mapBrowserEvent) { handleDownEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) { if (!mouseOnly(mapBrowserEvent)) {
return false; return false;
} }
@@ -131,6 +120,7 @@ function handleDownEvent(mapBrowserEvent) {
} else { } else {
return false; return false;
} }
}
} }
export default DragRotate; export default DragRotate;
+13 -26
View File
@@ -38,11 +38,7 @@ class DragRotateAndZoom extends PointerInteraction {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super({ super(/** @type {import("./Pointer.js").Options} */ (options));
handleDownEvent: handleDownEvent,
handleDragEvent: handleDragEvent,
handleUpEvent: handleUpEvent
});
/** /**
* @private * @private
@@ -76,14 +72,10 @@ class DragRotateAndZoom extends PointerInteraction {
} }
} /**
* @inheritDoc
/**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @this {DragRotateAndZoom}
*/ */
function handleDragEvent(mapBrowserEvent) { handleDragEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) { if (!mouseOnly(mapBrowserEvent)) {
return; return;
} }
@@ -109,15 +101,12 @@ function handleDragEvent(mapBrowserEvent) {
this.lastScaleDelta_ = this.lastMagnitude_ / magnitude; this.lastScaleDelta_ = this.lastMagnitude_ / magnitude;
} }
this.lastMagnitude_ = magnitude; this.lastMagnitude_ = magnitude;
} }
/**
/** * @inheritDoc
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Stop drag sequence?
* @this {DragRotateAndZoom}
*/ */
function handleUpEvent(mapBrowserEvent) { handleUpEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) { if (!mouseOnly(mapBrowserEvent)) {
return true; return true;
} }
@@ -130,15 +119,12 @@ function handleUpEvent(mapBrowserEvent) {
zoom(view, view.getResolution(), undefined, this.duration_, direction); zoom(view, view.getResolution(), undefined, this.duration_, direction);
this.lastScaleDelta_ = 0; this.lastScaleDelta_ = 0;
return false; return false;
} }
/**
/** * @inheritDoc
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Start drag sequence?
* @this {DragRotateAndZoom}
*/ */
function handleDownEvent(mapBrowserEvent) { handleDownEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) { if (!mouseOnly(mapBrowserEvent)) {
return false; return false;
} }
@@ -151,6 +137,7 @@ function handleDownEvent(mapBrowserEvent) {
} else { } else {
return false; return false;
} }
}
} }
export default DragRotateAndZoom; export default DragRotateAndZoom;
+124 -133
View File
@@ -21,7 +21,7 @@ import MultiPolygon from '../geom/MultiPolygon.js';
import {POINTER_TYPE} from '../pointer/MouseSource.js'; import {POINTER_TYPE} from '../pointer/MouseSource.js';
import Point from '../geom/Point.js'; import Point from '../geom/Point.js';
import Polygon, {fromCircle, makeRegular} from '../geom/Polygon.js'; import Polygon, {fromCircle, makeRegular} from '../geom/Polygon.js';
import PointerInteraction, {handleEvent as handlePointerEvent} from '../interaction/Pointer.js'; import PointerInteraction from '../interaction/Pointer.js';
import InteractionProperty from '../interaction/Property.js'; import InteractionProperty from '../interaction/Property.js';
import VectorLayer from '../layer/Vector.js'; import VectorLayer from '../layer/Vector.js';
import VectorSource from '../source/Vector.js'; import VectorSource from '../source/Vector.js';
@@ -186,12 +186,12 @@ class Draw extends PointerInteraction {
*/ */
constructor(options) { constructor(options) {
super({ const pointerOptions = /** @type {import("./Pointer.js").Options} */ (options);
handleDownEvent: handleDownEvent, if (!pointerOptions.stopDown) {
handleEvent: handleEvent, pointerOptions.stopDown = FALSE;
handleUpEvent: handleUpEvent, }
stopDown: FALSE
}); super(pointerOptions);
/** /**
* @type {boolean} * @type {boolean}
@@ -472,6 +472,123 @@ class Draw extends PointerInteraction {
return this.overlay_; return this.overlay_;
} }
/**
* Handles the {@link module:ol/MapBrowserEvent map browser event} and may actually draw or finish the drawing.
* @override
* @api
*/
handleEvent(event) {
if (event.originalEvent.type === EventType.CONTEXTMENU) {
// Avoid context menu for long taps when drawing on mobile
event.preventDefault();
}
this.freehand_ = this.mode_ !== Mode.POINT && this.freehandCondition_(event);
let move = event.type === MapBrowserEventType.POINTERMOVE;
let pass = true;
if (!this.freehand_ && this.lastDragTime_ && event.type === MapBrowserEventType.POINTERDRAG) {
const now = Date.now();
if (now - this.lastDragTime_ >= this.dragVertexDelay_) {
this.downPx_ = event.pixel;
this.shouldHandle_ = !this.freehand_;
move = true;
} else {
this.lastDragTime_ = undefined;
}
if (this.shouldHandle_ && this.downTimeout_ !== undefined) {
clearTimeout(this.downTimeout_);
this.downTimeout_ = undefined;
}
}
if (this.freehand_ &&
event.type === MapBrowserEventType.POINTERDRAG &&
this.sketchFeature_ !== null) {
this.addToDrawing_(event);
pass = false;
} else if (this.freehand_ &&
event.type === MapBrowserEventType.POINTERDOWN) {
pass = false;
} else if (move) {
pass = event.type === MapBrowserEventType.POINTERMOVE;
if (pass && this.freehand_) {
pass = this.handlePointerMove_(event);
} else if (/** @type {MapBrowserPointerEvent} */ (event).pointerEvent.pointerType == POINTER_TYPE ||
(event.type === MapBrowserEventType.POINTERDRAG && this.downTimeout_ === undefined)) {
this.handlePointerMove_(event);
}
} else if (event.type === MapBrowserEventType.DBLCLICK) {
pass = false;
}
return super.handleEvent(event) && pass;
}
/**
* @inheritDoc
*/
handleDownEvent(event) {
this.shouldHandle_ = !this.freehand_;
if (this.freehand_) {
this.downPx_ = event.pixel;
if (!this.finishCoordinate_) {
this.startDrawing_(event);
}
return true;
} else if (this.condition_(event)) {
this.lastDragTime_ = Date.now();
this.downTimeout_ = setTimeout(function() {
this.handlePointerMove_(new MapBrowserPointerEvent(
MapBrowserEventType.POINTERMOVE, event.map, event.pointerEvent, false, event.frameState));
}.bind(this), this.dragVertexDelay_);
this.downPx_ = event.pixel;
return true;
} else {
return false;
}
}
/**
* @inheritDoc
*/
handleUpEvent(event) {
let pass = true;
if (this.downTimeout_) {
clearTimeout(this.downTimeout_);
this.downTimeout_ = undefined;
}
this.handlePointerMove_(event);
const circleMode = this.mode_ === Mode.CIRCLE;
if (this.shouldHandle_) {
if (!this.finishCoordinate_) {
this.startDrawing_(event);
if (this.mode_ === Mode.POINT) {
this.finishDrawing();
}
} else if (this.freehand_ || circleMode) {
this.finishDrawing();
} else if (this.atFinish_(event)) {
if (this.finishCondition_(event)) {
this.finishDrawing();
}
} else {
this.addToDrawing_(event);
}
pass = false;
} else if (this.freehand_) {
this.finishCoordinate_ = null;
this.abortDrawing_();
}
if (!pass && this.stopClick_) {
event.stopPropagation();
}
return pass;
}
/** /**
* Handle move events. * Handle move events.
* @param {import("../MapBrowserEvent.js").default} event A move event. * @param {import("../MapBrowserEvent.js").default} event A move event.
@@ -842,132 +959,6 @@ function getDefaultStyleFunction() {
} }
/**
* Handles the {@link module:ol/MapBrowserEvent map browser event} and may actually
* draw or finish the drawing.
* @param {import("../MapBrowserEvent.js").default} event Map browser event.
* @return {boolean} `false` to stop event propagation.
* @this {Draw}
* @api
*/
export function handleEvent(event) {
if (event.originalEvent.type === EventType.CONTEXTMENU) {
// Avoid context menu for long taps when drawing on mobile
event.preventDefault();
}
this.freehand_ = this.mode_ !== Mode.POINT && this.freehandCondition_(event);
let move = event.type === MapBrowserEventType.POINTERMOVE;
let pass = true;
if (!this.freehand_ && this.lastDragTime_ && event.type === MapBrowserEventType.POINTERDRAG) {
const now = Date.now();
if (now - this.lastDragTime_ >= this.dragVertexDelay_) {
this.downPx_ = event.pixel;
this.shouldHandle_ = !this.freehand_;
move = true;
} else {
this.lastDragTime_ = undefined;
}
if (this.shouldHandle_ && this.downTimeout_ !== undefined) {
clearTimeout(this.downTimeout_);
this.downTimeout_ = undefined;
}
}
if (this.freehand_ &&
event.type === MapBrowserEventType.POINTERDRAG &&
this.sketchFeature_ !== null) {
this.addToDrawing_(event);
pass = false;
} else if (this.freehand_ &&
event.type === MapBrowserEventType.POINTERDOWN) {
pass = false;
} else if (move) {
pass = event.type === MapBrowserEventType.POINTERMOVE;
if (pass && this.freehand_) {
pass = this.handlePointerMove_(event);
} else if (/** @type {MapBrowserPointerEvent} */ (event).pointerEvent.pointerType == POINTER_TYPE ||
(event.type === MapBrowserEventType.POINTERDRAG && this.downTimeout_ === undefined)) {
this.handlePointerMove_(event);
}
} else if (event.type === MapBrowserEventType.DBLCLICK) {
pass = false;
}
return handlePointerEvent.call(this, event) && pass;
}
/**
* @param {MapBrowserPointerEvent} event Event.
* @return {boolean} Start drag sequence?
* @this {Draw}
*/
function handleDownEvent(event) {
this.shouldHandle_ = !this.freehand_;
if (this.freehand_) {
this.downPx_ = event.pixel;
if (!this.finishCoordinate_) {
this.startDrawing_(event);
}
return true;
} else if (this.condition_(event)) {
this.lastDragTime_ = Date.now();
this.downTimeout_ = setTimeout(function() {
this.handlePointerMove_(new MapBrowserPointerEvent(
MapBrowserEventType.POINTERMOVE, event.map, event.pointerEvent, false, event.frameState));
}.bind(this), this.dragVertexDelay_);
this.downPx_ = event.pixel;
return true;
} else {
return false;
}
}
/**
* @param {MapBrowserPointerEvent} event Event.
* @return {boolean} Stop drag sequence?
* @this {Draw}
*/
function handleUpEvent(event) {
let pass = true;
if (this.downTimeout_) {
clearTimeout(this.downTimeout_);
this.downTimeout_ = undefined;
}
this.handlePointerMove_(event);
const circleMode = this.mode_ === Mode.CIRCLE;
if (this.shouldHandle_) {
if (!this.finishCoordinate_) {
this.startDrawing_(event);
if (this.mode_ === Mode.POINT) {
this.finishDrawing();
}
} else if (this.freehand_ || circleMode) {
this.finishDrawing();
} else if (this.atFinish_(event)) {
if (this.finishCondition_(event)) {
this.finishDrawing();
}
} else {
this.addToDrawing_(event);
}
pass = false;
} else if (this.freehand_) {
this.finishCoordinate_ = null;
this.abortDrawing_();
}
if (!pass && this.stopClick_) {
event.stopPropagation();
}
return pass;
}
/** /**
* Create a `geometryFunction` for `type: 'Circle'` that will create a regular * Create a `geometryFunction` for `type: 'Circle'` that will create a regular
* polygon with a user specified number of sides and start angle instead of an * polygon with a user specified number of sides and start angle instead of an
+52 -65
View File
@@ -10,7 +10,7 @@ import {boundingExtent, getArea} from '../extent.js';
import GeometryType from '../geom/GeometryType.js'; import GeometryType from '../geom/GeometryType.js';
import Point from '../geom/Point.js'; import Point from '../geom/Point.js';
import {fromExtent as polygonFromExtent} from '../geom/Polygon.js'; import {fromExtent as polygonFromExtent} from '../geom/Polygon.js';
import PointerInteraction, {handleEvent as handlePointerEvent} from '../interaction/Pointer.js'; import PointerInteraction from '../interaction/Pointer.js';
import VectorLayer from '../layer/Vector.js'; import VectorLayer from '../layer/Vector.js';
import VectorSource from '../source/Vector.js'; import VectorSource from '../source/Vector.js';
import {createEditingStyle} from '../style/Style.js'; import {createEditingStyle} from '../style/Style.js';
@@ -85,15 +85,10 @@ class ExtentInteraction extends PointerInteraction {
*/ */
constructor(opt_options) { constructor(opt_options) {
super({
handleDownEvent: handleDownEvent,
handleDragEvent: handleDragEvent,
handleEvent: handleEvent,
handleUpEvent: handleUpEvent
});
const options = opt_options || {}; const options = opt_options || {};
super(/** @type {import("./Pointer.js").Options} */ (options));
/** /**
* Extent of the drawn box * Extent of the drawn box
* @type {import("../extent.js").Extent} * @type {import("../extent.js").Extent}
@@ -248,7 +243,7 @@ class ExtentInteraction extends PointerInteraction {
extentFeature = new Feature(polygonFromExtent(extent)); extentFeature = new Feature(polygonFromExtent(extent));
} }
this.extentFeature_ = extentFeature; this.extentFeature_ = extentFeature;
this.extentOverlay_.getSource().addFeature(extentFeature); /** @type {VectorSource} */ (this.extentOverlay_.getSource()).addFeature(extentFeature);
} else { } else {
if (!extent) { if (!extent) {
extentFeature.setGeometry(undefined); extentFeature.setGeometry(undefined);
@@ -269,7 +264,7 @@ class ExtentInteraction extends PointerInteraction {
if (!vertexFeature) { if (!vertexFeature) {
vertexFeature = new Feature(new Point(vertex)); vertexFeature = new Feature(new Point(vertex));
this.vertexFeature_ = vertexFeature; this.vertexFeature_ = vertexFeature;
this.vertexOverlay_.getSource().addFeature(vertexFeature); /** @type {VectorSource} */ (this.vertexOverlay_.getSource()).addFeature(vertexFeature);
} else { } else {
const geometry = /** @type {Point} */ (vertexFeature.getGeometry()); const geometry = /** @type {Point} */ (vertexFeature.getGeometry());
geometry.setCoordinates(vertex); geometry.setCoordinates(vertex);
@@ -280,42 +275,7 @@ class ExtentInteraction extends PointerInteraction {
/** /**
* @inheritDoc * @inheritDoc
*/ */
setMap(map) { handleEvent(mapBrowserEvent) {
this.extentOverlay_.setMap(map);
this.vertexOverlay_.setMap(map);
super.setMap(map);
}
/**
* Returns the current drawn extent in the view projection
*
* @return {import("../extent.js").Extent} Drawn extent in the view projection.
* @api
*/
getExtent() {
return this.extent_;
}
/**
* Manually sets the drawn extent, using the view projection.
*
* @param {import("../extent.js").Extent} extent Extent
* @api
*/
setExtent(extent) {
//Null extent means no bbox
this.extent_ = extent ? extent : null;
this.createOrUpdateExtentFeature_(extent);
this.dispatchEvent(new ExtentInteractionEvent(this.extent_));
}
}
/**
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Propagate event?
* @this {ExtentInteraction}
*/
function handleEvent(mapBrowserEvent) {
if (!(mapBrowserEvent instanceof MapBrowserPointerEvent)) { if (!(mapBrowserEvent instanceof MapBrowserPointerEvent)) {
return true; return true;
} }
@@ -324,17 +284,15 @@ function handleEvent(mapBrowserEvent) {
this.handlePointerMove_(mapBrowserEvent); this.handlePointerMove_(mapBrowserEvent);
} }
//call pointer to determine up/down/drag //call pointer to determine up/down/drag
handlePointerEvent.call(this, mapBrowserEvent); super.handleEvent(mapBrowserEvent);
//return false to stop propagation //return false to stop propagation
return false; return false;
} }
/** /**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event. * @inheritDoc
* @return {boolean} Event handled?
* @this {ExtentInteraction}
*/ */
function handleDownEvent(mapBrowserEvent) { handleDownEvent(mapBrowserEvent) {
const pixel = mapBrowserEvent.pixel; const pixel = mapBrowserEvent.pixel;
const map = mapBrowserEvent.map; const map = mapBrowserEvent.map;
@@ -386,28 +344,24 @@ function handleDownEvent(mapBrowserEvent) {
this.pointerHandler_ = getPointHandler(vertex); this.pointerHandler_ = getPointHandler(vertex);
} }
return true; //event handled; start downup sequence return true; //event handled; start downup sequence
} }
/** /**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event. * @inheritDoc
* @return {boolean} Event handled?
* @this {ExtentInteraction}
*/ */
function handleDragEvent(mapBrowserEvent) { handleDragEvent(mapBrowserEvent) {
if (this.pointerHandler_) { if (this.pointerHandler_) {
const pixelCoordinate = mapBrowserEvent.coordinate; const pixelCoordinate = mapBrowserEvent.coordinate;
this.setExtent(this.pointerHandler_(pixelCoordinate)); this.setExtent(this.pointerHandler_(pixelCoordinate));
this.createOrUpdatePointerFeature_(pixelCoordinate); this.createOrUpdatePointerFeature_(pixelCoordinate);
} }
return true; return true;
} }
/** /**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event. * @inheritDoc
* @return {boolean} Stop drag sequence?
* @this {ExtentInteraction}
*/ */
function handleUpEvent(mapBrowserEvent) { handleUpEvent(mapBrowserEvent) {
this.pointerHandler_ = null; this.pointerHandler_ = null;
//If bbox is zero area, set to null; //If bbox is zero area, set to null;
const extent = this.getExtent(); const extent = this.getExtent();
@@ -415,6 +369,39 @@ function handleUpEvent(mapBrowserEvent) {
this.setExtent(null); this.setExtent(null);
} }
return false; //Stop handling downup sequence return false; //Stop handling downup sequence
}
/**
* @inheritDoc
*/
setMap(map) {
this.extentOverlay_.setMap(map);
this.vertexOverlay_.setMap(map);
super.setMap(map);
}
/**
* Returns the current drawn extent in the view projection
*
* @return {import("../extent.js").Extent} Drawn extent in the view projection.
* @api
*/
getExtent() {
return this.extent_;
}
/**
* Manually sets the drawn extent, using the view projection.
*
* @param {import("../extent.js").Extent} extent Extent
* @api
*/
setExtent(extent) {
//Null extent means no bbox
this.extent_ = extent ? extent : null;
this.createOrUpdateExtentFeature_(extent);
this.dispatchEvent(new ExtentInteractionEvent(this.extent_));
}
} }
/** /**
+14 -6
View File
@@ -38,6 +38,10 @@ class Interaction extends BaseObject {
constructor(options) { constructor(options) {
super(); super();
if (options.handleEvent) {
this.handleEvent = options.handleEvent;
}
/** /**
* @private * @private
* @type {import("../PluggableMap.js").default} * @type {import("../PluggableMap.js").default}
@@ -45,12 +49,6 @@ class Interaction extends BaseObject {
this.map_ = null; this.map_ = null;
this.setActive(true); this.setActive(true);
/**
* @type {function(import("../MapBrowserEvent.js").default):boolean}
*/
this.handleEvent = options.handleEvent;
} }
/** /**
@@ -72,6 +70,16 @@ class Interaction extends BaseObject {
return this.map_; return this.map_;
} }
/**
* Handles the {@link module:ol/MapBrowserEvent map browser event}.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
* @return {boolean} `false` to stop event propagation.
* @api
*/
handleEvent(mapBrowserEvent) {
return true;
}
/** /**
* Activate or deactivate the interaction. * Activate or deactivate the interaction.
* @param {boolean} active Active. * @param {boolean} active Active.
+207 -225
View File
@@ -16,7 +16,7 @@ import {always, primaryAction, altKeyOnly, singleClick} from '../events/conditio
import {boundingExtent, buffer, createOrUpdateFromCoordinate} from '../extent.js'; import {boundingExtent, buffer, createOrUpdateFromCoordinate} from '../extent.js';
import GeometryType from '../geom/GeometryType.js'; import GeometryType from '../geom/GeometryType.js';
import Point from '../geom/Point.js'; import Point from '../geom/Point.js';
import PointerInteraction, {handleEvent as handlePointerEvent} from '../interaction/Pointer.js'; import PointerInteraction from '../interaction/Pointer.js';
import VectorLayer from '../layer/Vector.js'; import VectorLayer from '../layer/Vector.js';
import VectorSource from '../source/Vector.js'; import VectorSource from '../source/Vector.js';
import VectorEventType from '../source/VectorEventType.js'; import VectorEventType from '../source/VectorEventType.js';
@@ -157,12 +157,7 @@ class Modify extends PointerInteraction {
*/ */
constructor(options) { constructor(options) {
super({ super(/** @type {import("./Pointer.js").Options} */ (options));
handleDownEvent: handleDownEvent,
handleDragEvent: handleDragEvent,
handleEvent: handleEvent,
handleUpEvent: handleUpEvent
});
/** /**
* @private * @private
@@ -170,7 +165,6 @@ class Modify extends PointerInteraction {
*/ */
this.condition_ = options.condition ? options.condition : primaryAction; this.condition_ = options.condition ? options.condition : primaryAction;
/** /**
* @private * @private
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Browser event. * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Browser event.
@@ -667,6 +661,211 @@ class Modify extends PointerInteraction {
return vertexFeature; return vertexFeature;
} }
/**
* Handles the {@link module:ol/MapBrowserEvent map browser event} and may modify the geometry.
* @override
*/
handleEvent(mapBrowserEvent) {
if (!(mapBrowserEvent instanceof MapBrowserPointerEvent)) {
return true;
}
this.lastPointerEvent_ = mapBrowserEvent;
let handled;
if (!mapBrowserEvent.map.getView().getInteracting() &&
mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE &&
!this.handlingDownUpSequence) {
this.handlePointerMove_(mapBrowserEvent);
}
if (this.vertexFeature_ && this.deleteCondition_(mapBrowserEvent)) {
if (mapBrowserEvent.type != MapBrowserEventType.SINGLECLICK || !this.ignoreNextSingleClick_) {
handled = this.removePoint();
} else {
handled = true;
}
}
if (mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK) {
this.ignoreNextSingleClick_ = false;
}
return super.handleEvent(mapBrowserEvent) && !handled;
}
/**
* @inheritDoc
*/
handleDragEvent(evt) {
this.ignoreNextSingleClick_ = false;
this.willModifyFeatures_(evt);
const vertex = evt.coordinate;
for (let i = 0, ii = this.dragSegments_.length; i < ii; ++i) {
const dragSegment = this.dragSegments_[i];
const segmentData = dragSegment[0];
const depth = segmentData.depth;
const geometry = segmentData.geometry;
let coordinates;
const segment = segmentData.segment;
const index = dragSegment[1];
while (vertex.length < geometry.getStride()) {
vertex.push(segment[index][vertex.length]);
}
switch (geometry.getType()) {
case GeometryType.POINT:
coordinates = vertex;
segment[0] = segment[1] = vertex;
break;
case GeometryType.MULTI_POINT:
coordinates = geometry.getCoordinates();
coordinates[segmentData.index] = vertex;
segment[0] = segment[1] = vertex;
break;
case GeometryType.LINE_STRING:
coordinates = geometry.getCoordinates();
coordinates[segmentData.index + index] = vertex;
segment[index] = vertex;
break;
case GeometryType.MULTI_LINE_STRING:
coordinates = geometry.getCoordinates();
coordinates[depth[0]][segmentData.index + index] = vertex;
segment[index] = vertex;
break;
case GeometryType.POLYGON:
coordinates = geometry.getCoordinates();
coordinates[depth[0]][segmentData.index + index] = vertex;
segment[index] = vertex;
break;
case GeometryType.MULTI_POLYGON:
coordinates = geometry.getCoordinates();
coordinates[depth[1]][depth[0]][segmentData.index + index] = vertex;
segment[index] = vertex;
break;
case GeometryType.CIRCLE:
segment[0] = segment[1] = vertex;
if (segmentData.index === CIRCLE_CENTER_INDEX) {
this.changingFeature_ = true;
geometry.setCenter(vertex);
this.changingFeature_ = false;
} else { // We're dragging the circle's circumference:
this.changingFeature_ = true;
geometry.setRadius(coordinateDistance(geometry.getCenter(), vertex));
this.changingFeature_ = false;
}
break;
default:
// pass
}
if (coordinates) {
this.setGeometryCoordinates_(geometry, coordinates);
}
}
this.createOrUpdateVertexFeature_(vertex);
}
/**
* @inheritDoc
*/
handleDownEvent(evt) {
if (!this.condition_(evt)) {
return false;
}
this.handlePointerAtPixel_(evt.pixel, evt.map);
const pixelCoordinate = evt.map.getCoordinateFromPixel(evt.pixel);
this.dragSegments_.length = 0;
this.modified_ = false;
const vertexFeature = this.vertexFeature_;
if (vertexFeature) {
const insertVertices = [];
const geometry = /** @type {Point} */ (vertexFeature.getGeometry());
const vertex = geometry.getCoordinates();
const vertexExtent = boundingExtent([vertex]);
const segmentDataMatches = this.rBush_.getInExtent(vertexExtent);
const componentSegments = {};
segmentDataMatches.sort(compareIndexes);
for (let i = 0, ii = segmentDataMatches.length; i < ii; ++i) {
const segmentDataMatch = segmentDataMatches[i];
const segment = segmentDataMatch.segment;
let uid = String(getUid(segmentDataMatch.feature));
const depth = segmentDataMatch.depth;
if (depth) {
uid += '-' + depth.join('-'); // separate feature components
}
if (!componentSegments[uid]) {
componentSegments[uid] = new Array(2);
}
if (segmentDataMatch.geometry.getType() === GeometryType.CIRCLE &&
segmentDataMatch.index === CIRCLE_CIRCUMFERENCE_INDEX) {
const closestVertex = closestOnSegmentData(pixelCoordinate, segmentDataMatch);
if (coordinatesEqual(closestVertex, vertex) && !componentSegments[uid][0]) {
this.dragSegments_.push([segmentDataMatch, 0]);
componentSegments[uid][0] = segmentDataMatch;
}
} else if (coordinatesEqual(segment[0], vertex) &&
!componentSegments[uid][0]) {
this.dragSegments_.push([segmentDataMatch, 0]);
componentSegments[uid][0] = segmentDataMatch;
} else if (coordinatesEqual(segment[1], vertex) &&
!componentSegments[uid][1]) {
// prevent dragging closed linestrings by the connecting node
if ((segmentDataMatch.geometry.getType() ===
GeometryType.LINE_STRING ||
segmentDataMatch.geometry.getType() ===
GeometryType.MULTI_LINE_STRING) &&
componentSegments[uid][0] &&
componentSegments[uid][0].index === 0) {
continue;
}
this.dragSegments_.push([segmentDataMatch, 1]);
componentSegments[uid][1] = segmentDataMatch;
} else if (this.insertVertexCondition_(evt) && getUid(segment) in this.vertexSegments_ &&
(!componentSegments[uid][0] && !componentSegments[uid][1])) {
insertVertices.push([segmentDataMatch, vertex]);
}
}
if (insertVertices.length) {
this.willModifyFeatures_(evt);
}
for (let j = insertVertices.length - 1; j >= 0; --j) {
this.insertVertex_.apply(this, insertVertices[j]);
}
}
return !!this.vertexFeature_;
}
/**
* @inheritDoc
*/
handleUpEvent(evt) {
for (let i = this.dragSegments_.length - 1; i >= 0; --i) {
const segmentData = this.dragSegments_[i][0];
const geometry = segmentData.geometry;
if (geometry.getType() === GeometryType.CIRCLE) {
// Update a circle object in the R* bush:
const coordinates = geometry.getCenter();
const centerSegmentData = segmentData.featureSegments[0];
const circumferenceSegmentData = segmentData.featureSegments[1];
centerSegmentData.segment[0] = centerSegmentData.segment[1] = coordinates;
circumferenceSegmentData.segment[0] = circumferenceSegmentData.segment[1] = coordinates;
this.rBush_.update(createOrUpdateFromCoordinate(coordinates), centerSegmentData);
this.rBush_.update(geometry.getExtent(), circumferenceSegmentData);
} else {
this.rBush_.update(boundingExtent(segmentData.segment), segmentData);
}
}
if (this.modified_) {
this.dispatchEvent(new ModifyEvent(ModifyEventType.MODIFYEND, this.features_, evt));
this.modified_ = false;
}
return false;
}
/** /**
* @param {import("../MapBrowserEvent.js").default} evt Event. * @param {import("../MapBrowserEvent.js").default} evt Event.
* @private * @private
@@ -985,223 +1184,6 @@ function compareIndexes(a, b) {
} }
/**
* @param {MapBrowserPointerEvent} evt Event.
* @return {boolean} Start drag sequence?
* @this {Modify}
*/
function handleDownEvent(evt) {
if (!this.condition_(evt)) {
return false;
}
this.handlePointerAtPixel_(evt.pixel, evt.map);
const pixelCoordinate = evt.map.getCoordinateFromPixel(evt.pixel);
this.dragSegments_.length = 0;
this.modified_ = false;
const vertexFeature = this.vertexFeature_;
if (vertexFeature) {
const insertVertices = [];
const geometry = /** @type {Point} */ (vertexFeature.getGeometry());
const vertex = geometry.getCoordinates();
const vertexExtent = boundingExtent([vertex]);
const segmentDataMatches = this.rBush_.getInExtent(vertexExtent);
const componentSegments = {};
segmentDataMatches.sort(compareIndexes);
for (let i = 0, ii = segmentDataMatches.length; i < ii; ++i) {
const segmentDataMatch = segmentDataMatches[i];
const segment = segmentDataMatch.segment;
let uid = String(getUid(segmentDataMatch.feature));
const depth = segmentDataMatch.depth;
if (depth) {
uid += '-' + depth.join('-'); // separate feature components
}
if (!componentSegments[uid]) {
componentSegments[uid] = new Array(2);
}
if (segmentDataMatch.geometry.getType() === GeometryType.CIRCLE &&
segmentDataMatch.index === CIRCLE_CIRCUMFERENCE_INDEX) {
const closestVertex = closestOnSegmentData(pixelCoordinate, segmentDataMatch);
if (coordinatesEqual(closestVertex, vertex) && !componentSegments[uid][0]) {
this.dragSegments_.push([segmentDataMatch, 0]);
componentSegments[uid][0] = segmentDataMatch;
}
} else if (coordinatesEqual(segment[0], vertex) &&
!componentSegments[uid][0]) {
this.dragSegments_.push([segmentDataMatch, 0]);
componentSegments[uid][0] = segmentDataMatch;
} else if (coordinatesEqual(segment[1], vertex) &&
!componentSegments[uid][1]) {
// prevent dragging closed linestrings by the connecting node
if ((segmentDataMatch.geometry.getType() ===
GeometryType.LINE_STRING ||
segmentDataMatch.geometry.getType() ===
GeometryType.MULTI_LINE_STRING) &&
componentSegments[uid][0] &&
componentSegments[uid][0].index === 0) {
continue;
}
this.dragSegments_.push([segmentDataMatch, 1]);
componentSegments[uid][1] = segmentDataMatch;
} else if (this.insertVertexCondition_(evt) && getUid(segment) in this.vertexSegments_ &&
(!componentSegments[uid][0] && !componentSegments[uid][1])) {
insertVertices.push([segmentDataMatch, vertex]);
}
}
if (insertVertices.length) {
this.willModifyFeatures_(evt);
}
for (let j = insertVertices.length - 1; j >= 0; --j) {
this.insertVertex_.apply(this, insertVertices[j]);
}
}
return !!this.vertexFeature_;
}
/**
* @param {MapBrowserPointerEvent} evt Event.
* @this {Modify}
*/
function handleDragEvent(evt) {
this.ignoreNextSingleClick_ = false;
this.willModifyFeatures_(evt);
const vertex = evt.coordinate;
for (let i = 0, ii = this.dragSegments_.length; i < ii; ++i) {
const dragSegment = this.dragSegments_[i];
const segmentData = dragSegment[0];
const depth = segmentData.depth;
const geometry = segmentData.geometry;
let coordinates;
const segment = segmentData.segment;
const index = dragSegment[1];
while (vertex.length < geometry.getStride()) {
vertex.push(segment[index][vertex.length]);
}
switch (geometry.getType()) {
case GeometryType.POINT:
coordinates = vertex;
segment[0] = segment[1] = vertex;
break;
case GeometryType.MULTI_POINT:
coordinates = geometry.getCoordinates();
coordinates[segmentData.index] = vertex;
segment[0] = segment[1] = vertex;
break;
case GeometryType.LINE_STRING:
coordinates = geometry.getCoordinates();
coordinates[segmentData.index + index] = vertex;
segment[index] = vertex;
break;
case GeometryType.MULTI_LINE_STRING:
coordinates = geometry.getCoordinates();
coordinates[depth[0]][segmentData.index + index] = vertex;
segment[index] = vertex;
break;
case GeometryType.POLYGON:
coordinates = geometry.getCoordinates();
coordinates[depth[0]][segmentData.index + index] = vertex;
segment[index] = vertex;
break;
case GeometryType.MULTI_POLYGON:
coordinates = geometry.getCoordinates();
coordinates[depth[1]][depth[0]][segmentData.index + index] = vertex;
segment[index] = vertex;
break;
case GeometryType.CIRCLE:
segment[0] = segment[1] = vertex;
if (segmentData.index === CIRCLE_CENTER_INDEX) {
this.changingFeature_ = true;
geometry.setCenter(vertex);
this.changingFeature_ = false;
} else { // We're dragging the circle's circumference:
this.changingFeature_ = true;
geometry.setRadius(coordinateDistance(geometry.getCenter(), vertex));
this.changingFeature_ = false;
}
break;
default:
// pass
}
if (coordinates) {
this.setGeometryCoordinates_(geometry, coordinates);
}
}
this.createOrUpdateVertexFeature_(vertex);
}
/**
* @param {MapBrowserPointerEvent} evt Event.
* @return {boolean} Stop drag sequence?
* @this {Modify}
*/
function handleUpEvent(evt) {
for (let i = this.dragSegments_.length - 1; i >= 0; --i) {
const segmentData = this.dragSegments_[i][0];
const geometry = segmentData.geometry;
if (geometry.getType() === GeometryType.CIRCLE) {
// Update a circle object in the R* bush:
const coordinates = geometry.getCenter();
const centerSegmentData = segmentData.featureSegments[0];
const circumferenceSegmentData = segmentData.featureSegments[1];
centerSegmentData.segment[0] = centerSegmentData.segment[1] = coordinates;
circumferenceSegmentData.segment[0] = circumferenceSegmentData.segment[1] = coordinates;
this.rBush_.update(createOrUpdateFromCoordinate(coordinates), centerSegmentData);
this.rBush_.update(geometry.getExtent(), circumferenceSegmentData);
} else {
this.rBush_.update(boundingExtent(segmentData.segment), segmentData);
}
}
if (this.modified_) {
this.dispatchEvent(new ModifyEvent(ModifyEventType.MODIFYEND, this.features_, evt));
this.modified_ = false;
}
return false;
}
/**
* Handles the {@link module:ol/MapBrowserEvent map browser event} and may modify the
* geometry.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
* @return {boolean} `false` to stop event propagation.
* @this {Modify}
*/
function handleEvent(mapBrowserEvent) {
if (!(mapBrowserEvent instanceof MapBrowserPointerEvent)) {
return true;
}
this.lastPointerEvent_ = mapBrowserEvent;
let handled;
if (!mapBrowserEvent.map.getView().getInteracting() &&
mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE &&
!this.handlingDownUpSequence) {
this.handlePointerMove_(mapBrowserEvent);
}
if (this.vertexFeature_ && this.deleteCondition_(mapBrowserEvent)) {
if (mapBrowserEvent.type != MapBrowserEventType.SINGLECLICK || !this.ignoreNextSingleClick_) {
handled = this.removePoint();
} else {
handled = true;
}
}
if (mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK) {
this.ignoreNextSingleClick_ = false;
}
return handlePointerEvent.call(this, mapBrowserEvent) && !handled;
}
/** /**
* Returns the distance from a point to a line segment. * Returns the distance from a point to a line segment.
* *
+39 -45
View File
@@ -54,11 +54,9 @@ class MouseWheelZoom extends Interaction {
*/ */
constructor(opt_options) { constructor(opt_options) {
super({ const options = opt_options ? opt_options : {};
handleEvent: handleEvent
});
const options = opt_options || {}; super(/** @type {import("./Interaction.js").InteractionOptions} */ (options));
/** /**
* @private * @private
@@ -158,47 +156,11 @@ class MouseWheelZoom extends Interaction {
} }
/** /**
* @private * Handles the {@link module:ol/MapBrowserEvent map browser event} (if it was a mousewheel-event) and eventually
* @param {import("../PluggableMap.js").default} map Map. * zooms the map.
* @override
*/ */
handleWheelZoom_(map) { handleEvent(mapBrowserEvent) {
const view = map.getView();
if (view.getAnimating()) {
view.cancelAnimations();
}
const maxDelta = MAX_DELTA;
const delta = clamp(this.delta_, -maxDelta, maxDelta);
zoomByDelta(view, -delta, this.lastAnchor_, this.duration_);
this.mode_ = undefined;
this.delta_ = 0;
this.lastAnchor_ = null;
this.startTime_ = undefined;
this.timeoutId_ = undefined;
}
/**
* Enable or disable using the mouse's location as an anchor when zooming
* @param {boolean} useAnchor true to zoom to the mouse's location, false
* to zoom to the center of the map
* @api
*/
setMouseAnchor(useAnchor) {
this.useAnchor_ = useAnchor;
if (!useAnchor) {
this.lastAnchor_ = null;
}
}
}
/**
* Handles the {@link module:ol/MapBrowserEvent map browser event} (if it was a
* mousewheel-event) and eventually zooms the map.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
* @return {boolean} Allow event propagation.
* @this {MouseWheelZoom}
*/
function handleEvent(mapBrowserEvent) {
if (!this.condition_(mapBrowserEvent)) { if (!this.condition_(mapBrowserEvent)) {
return true; return true;
} }
@@ -312,7 +274,39 @@ function handleEvent(mapBrowserEvent) {
this.timeoutId_ = setTimeout(this.handleWheelZoom_.bind(this, map), timeLeft); this.timeoutId_ = setTimeout(this.handleWheelZoom_.bind(this, map), timeLeft);
return false; return false;
}
/**
* @private
* @param {import("../PluggableMap.js").default} map Map.
*/
handleWheelZoom_(map) {
const view = map.getView();
if (view.getAnimating()) {
view.cancelAnimations();
}
const maxDelta = MAX_DELTA;
const delta = clamp(this.delta_, -maxDelta, maxDelta);
zoomByDelta(view, -delta, this.lastAnchor_, this.duration_);
this.mode_ = undefined;
this.delta_ = 0;
this.lastAnchor_ = null;
this.startTime_ = undefined;
this.timeoutId_ = undefined;
}
/**
* Enable or disable using the mouse's location as an anchor when zooming
* @param {boolean} useAnchor true to zoom to the mouse's location, false
* to zoom to the center of the map
* @api
*/
setMouseAnchor(useAnchor) {
this.useAnchor_ = useAnchor;
if (!useAnchor) {
this.lastAnchor_ = null;
}
}
} }
export default MouseWheelZoom; export default MouseWheelZoom;
+20 -28
View File
@@ -28,14 +28,15 @@ class PinchRotate extends PointerInteraction {
*/ */
constructor(opt_options) { constructor(opt_options) {
super({ const options = opt_options ? opt_options : {};
handleDownEvent: handleDownEvent,
handleDragEvent: handleDragEvent,
handleUpEvent: handleUpEvent,
stopDown: FALSE
});
const options = opt_options || {}; const pointerOptions = /** @type {import("./Pointer.js").Options} */ (options);
if (!pointerOptions.stopDown) {
pointerOptions.stopDown = FALSE;
}
super(pointerOptions);
/** /**
* @private * @private
@@ -75,14 +76,10 @@ class PinchRotate extends PointerInteraction {
} }
} /**
* @inheritDoc
/**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @this {PinchRotate}
*/ */
function handleDragEvent(mapBrowserEvent) { handleDragEvent(mapBrowserEvent) {
let rotationDelta = 0.0; let rotationDelta = 0.0;
const touch0 = this.targetPointers[0]; const touch0 = this.targetPointers[0];
@@ -125,15 +122,12 @@ function handleDragEvent(mapBrowserEvent) {
map.render(); map.render();
rotateWithoutConstraints(view, rotation + rotationDelta, this.anchor_); rotateWithoutConstraints(view, rotation + rotationDelta, this.anchor_);
} }
} }
/**
/** * @inheritDoc
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Stop drag sequence?
* @this {PinchRotate}
*/ */
function handleUpEvent(mapBrowserEvent) { handleUpEvent(mapBrowserEvent) {
if (this.targetPointers.length < 2) { if (this.targetPointers.length < 2) {
const map = mapBrowserEvent.map; const map = mapBrowserEvent.map;
const view = map.getView(); const view = map.getView();
@@ -146,15 +140,12 @@ function handleUpEvent(mapBrowserEvent) {
} else { } else {
return true; return true;
} }
} }
/**
/** * @inheritDoc
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Start drag sequence?
* @this {PinchRotate}
*/ */
function handleDownEvent(mapBrowserEvent) { handleDownEvent(mapBrowserEvent) {
if (this.targetPointers.length >= 2) { if (this.targetPointers.length >= 2) {
const map = mapBrowserEvent.map; const map = mapBrowserEvent.map;
this.anchor_ = null; this.anchor_ = null;
@@ -168,6 +159,7 @@ function handleDownEvent(mapBrowserEvent) {
} else { } else {
return false; return false;
} }
}
} }
export default PinchRotate; export default PinchRotate;
+20 -28
View File
@@ -27,15 +27,16 @@ class PinchZoom extends PointerInteraction {
*/ */
constructor(opt_options) { constructor(opt_options) {
super({
handleDownEvent: handleDownEvent,
handleDragEvent: handleDragEvent,
handleUpEvent: handleUpEvent,
stopDown: FALSE
});
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
const pointerOptions = /** @type {import("./Pointer.js").Options} */ (options);
if (!pointerOptions.stopDown) {
pointerOptions.stopDown = FALSE;
}
super(pointerOptions);
/** /**
* @private * @private
* @type {boolean} * @type {boolean}
@@ -68,14 +69,10 @@ class PinchZoom extends PointerInteraction {
} }
} /**
* @inheritDoc
/**
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @this {PinchZoom}
*/ */
function handleDragEvent(mapBrowserEvent) { handleDragEvent(mapBrowserEvent) {
let scaleDelta = 1.0; let scaleDelta = 1.0;
const touch0 = this.targetPointers[0]; const touch0 = this.targetPointers[0];
@@ -120,15 +117,12 @@ function handleDragEvent(mapBrowserEvent) {
// scale, bypass the resolution constraint // scale, bypass the resolution constraint
map.render(); map.render();
zoomWithoutConstraints(view, newResolution, this.anchor_); zoomWithoutConstraints(view, newResolution, this.anchor_);
} }
/**
/** * @inheritDoc
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Stop drag sequence?
* @this {PinchZoom}
*/ */
function handleUpEvent(mapBrowserEvent) { handleUpEvent(mapBrowserEvent) {
if (this.targetPointers.length < 2) { if (this.targetPointers.length < 2) {
const map = mapBrowserEvent.map; const map = mapBrowserEvent.map;
const view = map.getView(); const view = map.getView();
@@ -147,15 +141,12 @@ function handleUpEvent(mapBrowserEvent) {
} else { } else {
return true; return true;
} }
} }
/**
/** * @inheritDoc
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
* @return {boolean} Start drag sequence?
* @this {PinchZoom}
*/ */
function handleDownEvent(mapBrowserEvent) { handleDownEvent(mapBrowserEvent) {
if (this.targetPointers.length >= 2) { if (this.targetPointers.length >= 2) {
const map = mapBrowserEvent.map; const map = mapBrowserEvent.map;
this.anchor_ = null; this.anchor_ = null;
@@ -168,6 +159,7 @@ function handleDownEvent(mapBrowserEvent) {
} else { } else {
return false; return false;
} }
}
} }
export default PinchZoom; export default PinchZoom;
+98 -114
View File
@@ -1,43 +1,12 @@
/** /**
* @module ol/interaction/Pointer * @module ol/interaction/Pointer
*/ */
import {FALSE, VOID} from '../functions.js';
import MapBrowserEventType from '../MapBrowserEventType.js'; import MapBrowserEventType from '../MapBrowserEventType.js';
import MapBrowserPointerEvent from '../MapBrowserPointerEvent.js'; import MapBrowserPointerEvent from '../MapBrowserPointerEvent.js';
import Interaction from '../interaction/Interaction.js'; import Interaction from '../interaction/Interaction.js';
import {getValues} from '../obj.js'; import {getValues} from '../obj.js';
/**
* @param {MapBrowserPointerEvent} mapBrowserEvent Event.
* @this {PointerInteraction}
*/
const handleDragEvent = VOID;
/**
* @param {MapBrowserPointerEvent} mapBrowserEvent Event.
* @return {boolean} Capture dragging.
* @this {PointerInteraction}
*/
const handleUpEvent = FALSE;
/**
* @param {MapBrowserPointerEvent} mapBrowserEvent Event.
* @return {boolean} Capture dragging.
* @this {PointerInteraction}
*/
const handleDownEvent = FALSE;
/**
* @param {MapBrowserPointerEvent} mapBrowserEvent Event.
* @this {PointerInteraction}
*/
const handleMoveEvent = VOID;
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {function(MapBrowserPointerEvent):boolean} [handleDownEvent] * @property {function(MapBrowserPointerEvent):boolean} [handleDownEvent]
@@ -58,7 +27,7 @@ const handleMoveEvent = VOID;
* @property {function(MapBrowserPointerEvent):boolean} [handleUpEvent] * @property {function(MapBrowserPointerEvent):boolean} [handleUpEvent]
* Function handling "up" events. If the function returns `false` then the * Function handling "up" events. If the function returns `false` then the
* current drag sequence is stopped. * current drag sequence is stopped.
* @property {function(boolean):boolean} stopDown * @property {function(boolean):boolean} [stopDown]
* Should the down event be propagated to other interactions, or should be * Should the down event be propagated to other interactions, or should be
* stopped? * stopped?
*/ */
@@ -83,37 +52,27 @@ class PointerInteraction extends Interaction {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super({ super(/** @type {import("./Interaction.js").InteractionOptions} */ (options));
handleEvent: options.handleEvent || handleEvent
});
/** if (options.handleDownEvent) {
* @type {function(MapBrowserPointerEvent):boolean} this.handleDownEvent = options.handleDownEvent;
* @private }
*/
this.handleDownEvent_ = options.handleDownEvent ?
options.handleDownEvent : handleDownEvent;
/** if (options.handleDragEvent) {
* @type {function(MapBrowserPointerEvent)} this.handleDragEvent = options.handleDragEvent;
* @private }
*/
this.handleDragEvent_ = options.handleDragEvent ?
options.handleDragEvent : handleDragEvent;
/** if (options.handleMoveEvent) {
* @type {function(MapBrowserPointerEvent)} this.handleMoveEvent = options.handleMoveEvent;
* @private }
*/
this.handleMoveEvent_ = options.handleMoveEvent ?
options.handleMoveEvent : handleMoveEvent;
/** if (options.handleUpEvent) {
* @type {function(MapBrowserPointerEvent):boolean} this.handleUpEvent = options.handleUpEvent;
* @private }
*/
this.handleUpEvent_ = options.handleUpEvent ? if (options.stopDown) {
options.handleUpEvent : handleUpEvent; this.stopDown = options.stopDown;
}
/** /**
* @type {boolean} * @type {boolean}
@@ -121,14 +80,6 @@ class PointerInteraction extends Interaction {
*/ */
this.handlingDownUpSequence = false; this.handlingDownUpSequence = false;
/**
* This function is used to determine if "down" events should be propagated
* to other interactions or should be stopped.
* @type {function(boolean):boolean}
* @protected
*/
this.stopDown = options.stopDown ? options.stopDown : stopDown;
/** /**
* @type {!Object<string, import("../pointer/PointerEvent.js").default>} * @type {!Object<string, import("../pointer/PointerEvent.js").default>}
* @private * @private
@@ -143,6 +94,86 @@ class PointerInteraction extends Interaction {
} }
/**
* Handle pointer down events.
* @param {MapBrowserPointerEvent} mapBrowserEvent Event.
* @return {boolean} If the event was consumed.
* @protected
*/
handleDownEvent(mapBrowserEvent) {
return false;
}
/**
* Handle pointer drag events.
* @param {MapBrowserPointerEvent} mapBrowserEvent Event.
* @protected
*/
handleDragEvent(mapBrowserEvent) {}
/**
* Handles the {@link module:ol/MapBrowserEvent map browser event} and may call into
* other functions, if event sequences like e.g. 'drag' or 'down-up' etc. are
* detected.
* @override
* @api
*/
handleEvent(mapBrowserEvent) {
if (!(mapBrowserEvent instanceof MapBrowserPointerEvent)) {
return true;
}
let stopEvent = false;
this.updateTrackedPointers_(mapBrowserEvent);
if (this.handlingDownUpSequence) {
if (mapBrowserEvent.type == MapBrowserEventType.POINTERDRAG) {
this.handleDragEvent(mapBrowserEvent);
} 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);
if (handled) {
mapBrowserEvent.preventDefault();
}
this.handlingDownUpSequence = handled;
stopEvent = this.stopDown(handled);
} else if (mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE) {
this.handleMoveEvent(mapBrowserEvent);
}
}
return !stopEvent;
}
/**
* Handle pointer move events.
* @param {MapBrowserPointerEvent} mapBrowserEvent Event.
* @protected
*/
handleMoveEvent(mapBrowserEvent) {}
/**
* Handle pointer up events.
* @param {MapBrowserPointerEvent} 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 {MapBrowserPointerEvent} mapBrowserEvent Event. * @param {MapBrowserPointerEvent} mapBrowserEvent Event.
* @private * @private
@@ -197,51 +228,4 @@ function isPointerDraggingEvent(mapBrowserEvent) {
} }
/**
* Handles the {@link module:ol/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.
* @this {PointerInteraction}
* @api
*/
export function handleEvent(mapBrowserEvent) {
if (!(mapBrowserEvent instanceof MapBrowserPointerEvent)) {
return true;
}
let stopEvent = false;
this.updateTrackedPointers_(mapBrowserEvent);
if (this.handlingDownUpSequence) {
if (mapBrowserEvent.type == MapBrowserEventType.POINTERDRAG) {
this.handleDragEvent_(mapBrowserEvent);
} 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);
if (handled) {
mapBrowserEvent.preventDefault();
}
this.handlingDownUpSequence = handled;
stopEvent = this.stopDown(handled);
} else if (mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE) {
this.handleMoveEvent_(mapBrowserEvent);
}
}
return !stopEvent;
}
export default PointerInteraction; export default PointerInteraction;
/**
* @param {boolean} handled Was the event handled by the interaction?
* @return {boolean} Should the `down` event be stopped?
*/
function stopDown(handled) {
return handled;
}
+37 -39
View File
@@ -11,7 +11,7 @@ import {boundingExtent, createEmpty} from '../extent.js';
import {TRUE, FALSE} from '../functions.js'; import {TRUE, FALSE} from '../functions.js';
import GeometryType from '../geom/GeometryType.js'; import GeometryType from '../geom/GeometryType.js';
import {fromCircle} from '../geom/Polygon.js'; import {fromCircle} from '../geom/Polygon.js';
import PointerInteraction, {handleEvent as handlePointerEvent} from '../interaction/Pointer.js'; import PointerInteraction from '../interaction/Pointer.js';
import {getValues} from '../obj.js'; import {getValues} from '../obj.js';
import {VectorSourceEvent} from '../source/Vector.js'; import {VectorSourceEvent} from '../source/Vector.js';
import VectorEventType from '../source/VectorEventType.js'; import VectorEventType from '../source/VectorEventType.js';
@@ -71,15 +71,20 @@ class Snap extends PointerInteraction {
*/ */
constructor(opt_options) { constructor(opt_options) {
super({
handleEvent: handleEvent,
handleDownEvent: TRUE,
handleUpEvent: handleUpEvent,
stopDown: FALSE
});
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
const pointerOptions = /** @type {import("./Pointer.js").Options} */ (options);
if (!pointerOptions.handleDownEvent) {
pointerOptions.handleDownEvent = TRUE;
}
if (!pointerOptions.stopDown) {
pointerOptions.stopDown = FALSE;
}
super(pointerOptions);
/** /**
* @type {import("../source/Vector.js").default} * @type {import("../source/Vector.js").default}
* @private * @private
@@ -239,6 +244,18 @@ class Snap extends PointerInteraction {
); );
} }
/**
* @inheritDoc
*/
handleEvent(evt) {
const result = this.snapTo(evt.pixel, evt.coordinate, evt.map);
if (result.snapped) {
evt.coordinate = result.vertex.slice(0, 2);
evt.pixel = result.vertexPixel;
}
return super.handleEvent(evt);
}
/** /**
* @param {import("../source/Vector.js").default|import("../Collection.js").CollectionEvent} evt Event. * @param {import("../source/Vector.js").default|import("../Collection.js").CollectionEvent} evt Event.
* @private * @private
@@ -283,6 +300,18 @@ class Snap extends PointerInteraction {
} }
} }
/**
* @inheritDoc
*/
handleUpEvent(evt) {
const featuresToUpdate = getValues(this.pendingFeatures_);
if (featuresToUpdate.length) {
featuresToUpdate.forEach(this.updateFeature_.bind(this));
this.pendingFeatures_ = {};
}
return false;
}
/** /**
* Remove a feature from the collection of features that we may snap to. * Remove a feature from the collection of features that we may snap to.
* @param {import("../Feature.js").default} feature Feature * @param {import("../Feature.js").default} feature Feature
@@ -587,37 +616,6 @@ class Snap extends PointerInteraction {
} }
/**
* Handle all pointer events events.
* @param {import("../MapBrowserEvent.js").default} evt A move event.
* @return {boolean} Pass the event to other interactions.
* @this {Snap}
*/
export function handleEvent(evt) {
const result = this.snapTo(evt.pixel, evt.coordinate, evt.map);
if (result.snapped) {
evt.coordinate = result.vertex.slice(0, 2);
evt.pixel = result.vertexPixel;
}
return handlePointerEvent.call(this, evt);
}
/**
* @param {import("../MapBrowserPointerEvent.js").default} evt Event.
* @return {boolean} Stop drag sequence?
* @this {Snap}
*/
function handleUpEvent(evt) {
const featuresToUpdate = getValues(this.pendingFeatures_);
if (featuresToUpdate.length) {
featuresToUpdate.forEach(this.updateFeature_.bind(this));
this.pendingFeatures_ = {};
}
return false;
}
/** /**
* Sort segments by distance, helper function * Sort segments by distance, helper function
* @param {SegmentData} a The first segment data. * @param {SegmentData} a The first segment data.
+82 -98
View File
@@ -98,15 +98,10 @@ class Translate extends PointerInteraction {
* @param {Options=} opt_options Options. * @param {Options=} opt_options Options.
*/ */
constructor(opt_options) { constructor(opt_options) {
super({
handleDownEvent: handleDownEvent,
handleDragEvent: handleDragEvent,
handleMoveEvent: handleMoveEvent,
handleUpEvent: handleUpEvent
});
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super(/** @type {import("./Pointer.js").Options} */ (options));
/** /**
* The last position we translated to. * The last position we translated to.
* @type {import("../coordinate.js").Coordinate} * @type {import("../coordinate.js").Coordinate}
@@ -160,6 +155,86 @@ class Translate extends PointerInteraction {
} }
/**
* @inheritDoc
*/
handleDownEvent(event) {
this.lastFeature_ = this.featuresAtPixel_(event.pixel, event.map);
if (!this.lastCoordinate_ && this.lastFeature_) {
this.lastCoordinate_ = event.coordinate;
this.handleMoveEvent(event);
const features = this.features_ || new Collection([this.lastFeature_]);
this.dispatchEvent(
new TranslateEvent(
TranslateEventType.TRANSLATESTART, features,
event.coordinate));
return true;
}
return false;
}
/**
* @inheritDoc
*/
handleUpEvent(event) {
if (this.lastCoordinate_) {
this.lastCoordinate_ = null;
this.handleMoveEvent(event);
const features = this.features_ || new Collection([this.lastFeature_]);
this.dispatchEvent(
new TranslateEvent(
TranslateEventType.TRANSLATEEND, features,
event.coordinate));
return true;
}
return false;
}
/**
* @inheritDoc
*/
handleDragEvent(event) {
if (this.lastCoordinate_) {
const newCoordinate = event.coordinate;
const deltaX = newCoordinate[0] - this.lastCoordinate_[0];
const deltaY = newCoordinate[1] - this.lastCoordinate_[1];
const features = this.features_ || new Collection([this.lastFeature_]);
features.forEach(function(feature) {
const geom = feature.getGeometry();
geom.translate(deltaX, deltaY);
feature.setGeometry(geom);
});
this.lastCoordinate_ = newCoordinate;
this.dispatchEvent(
new TranslateEvent(
TranslateEventType.TRANSLATING, features,
newCoordinate));
}
}
/**
* @inheritDoc
*/
handleMoveEvent(event) {
const elem = event.map.getViewport();
// Change the cursor to grab/grabbing if hovering any of the features managed
// by the interaction
if (this.featuresAtPixel_(event.pixel, event.map)) {
elem.classList.remove(this.lastCoordinate_ ? 'ol-grab' : 'ol-grabbing');
elem.classList.add(this.lastCoordinate_ ? 'ol-grabbing' : 'ol-grab');
} else {
elem.classList.remove('ol-grab', 'ol-grabbing');
}
}
/** /**
* Tests to see if the given coordinates intersects any of our selected * Tests to see if the given coordinates intersects any of our selected
* features. * features.
@@ -234,95 +309,4 @@ class Translate extends PointerInteraction {
} }
} }
/**
* @param {import("../MapBrowserPointerEvent.js").default} event Event.
* @return {boolean} Start drag sequence?
* @this {Translate}
*/
function handleDownEvent(event) {
this.lastFeature_ = this.featuresAtPixel_(event.pixel, event.map);
if (!this.lastCoordinate_ && this.lastFeature_) {
this.lastCoordinate_ = event.coordinate;
handleMoveEvent.call(this, event);
const features = this.features_ || new Collection([this.lastFeature_]);
this.dispatchEvent(
new TranslateEvent(
TranslateEventType.TRANSLATESTART, features,
event.coordinate));
return true;
}
return false;
}
/**
* @param {import("../MapBrowserPointerEvent.js").default} event Event.
* @return {boolean} Stop drag sequence?
* @this {Translate}
*/
function handleUpEvent(event) {
if (this.lastCoordinate_) {
this.lastCoordinate_ = null;
handleMoveEvent.call(this, event);
const features = this.features_ || new Collection([this.lastFeature_]);
this.dispatchEvent(
new TranslateEvent(
TranslateEventType.TRANSLATEEND, features,
event.coordinate));
return true;
}
return false;
}
/**
* @param {import("../MapBrowserPointerEvent.js").default} event Event.
* @this {Translate}
*/
function handleDragEvent(event) {
if (this.lastCoordinate_) {
const newCoordinate = event.coordinate;
const deltaX = newCoordinate[0] - this.lastCoordinate_[0];
const deltaY = newCoordinate[1] - this.lastCoordinate_[1];
const features = this.features_ || new Collection([this.lastFeature_]);
features.forEach(function(feature) {
const geom = feature.getGeometry();
geom.translate(deltaX, deltaY);
feature.setGeometry(geom);
});
this.lastCoordinate_ = newCoordinate;
this.dispatchEvent(
new TranslateEvent(
TranslateEventType.TRANSLATING, features,
newCoordinate));
}
}
/**
* @param {import("../MapBrowserEvent.js").default} event Event.
* @this {Translate}
*/
function handleMoveEvent(event) {
const elem = event.map.getViewport();
// Change the cursor to grab/grabbing if hovering any of the features managed
// by the interaction
if (this.featuresAtPixel_(event.pixel, event.map)) {
elem.classList.remove(this.lastCoordinate_ ? 'ol-grab' : 'ol-grabbing');
elem.classList.add(this.lastCoordinate_ ? 'ol-grabbing' : 'ol-grab');
} else {
elem.classList.remove('ol-grab', 'ol-grabbing');
}
}
export default Translate; export default Translate;
@@ -17,7 +17,7 @@ describe('ol.interaction.DragRotateAndZoom', function() {
}); });
describe('#handleDragEvent_()', function() { describe('#handleDragEvent()', function() {
let target, map, interaction; let target, map, interaction;
@@ -64,7 +64,7 @@ describe('ol.interaction.DragRotateAndZoom', function() {
let view = map.getView(); let view = map.getView();
let spy = sinon.spy(view, 'rotate'); let spy = sinon.spy(view, 'rotate');
interaction.handleDragEvent_(event); interaction.handleDragEvent(event);
expect(spy.callCount).to.be(1); expect(spy.callCount).to.be(1);
expect(interaction.lastAngle_).to.be(-0.8308214428190254); expect(interaction.lastAngle_).to.be(-0.8308214428190254);
view.rotate.restore(); view.rotate.restore();
@@ -82,7 +82,7 @@ describe('ol.interaction.DragRotateAndZoom', function() {
true); true);
spy = sinon.spy(view, 'rotate'); spy = sinon.spy(view, 'rotate');
interaction.handleDragEvent_(event); interaction.handleDragEvent(event);
expect(spy.callCount).to.be(0); expect(spy.callCount).to.be(0);
view.rotate.restore(); view.rotate.restore();
}); });
@@ -2,6 +2,7 @@ import Map from '../../../../src/ol/Map.js';
import View from '../../../../src/ol/View.js'; import View from '../../../../src/ol/View.js';
import EventTarget from '../../../../src/ol/events/Target.js'; import EventTarget from '../../../../src/ol/events/Target.js';
import Interaction, {zoomByDelta} from '../../../../src/ol/interaction/Interaction.js'; import Interaction, {zoomByDelta} from '../../../../src/ol/interaction/Interaction.js';
import {FALSE} from '../../../../src/ol/functions.js';
describe('ol.interaction.Interaction', function() { describe('ol.interaction.Interaction', function() {
@@ -56,6 +57,36 @@ describe('ol.interaction.Interaction', function() {
}); });
describe('#handleEvent()', function() {
class MockInteraction extends Interaction {
constructor() {
super(...arguments);
}
handleEvent(mapBrowserEvent) {
return false;
}
}
it('has a default event handler', function() {
const interaction = new Interaction({});
expect(interaction.handleEvent()).to.be(true);
});
it('allows event handler overrides via options', function() {
const interaction = new Interaction({
handleEvent: FALSE
});
expect(interaction.handleEvent()).to.be(false);
});
it('allows event handler overrides via class extension', function() {
const interaction = new MockInteraction({});
expect(interaction.handleEvent()).to.be(false);
});
});
describe('zoomByDelta()', function() { describe('zoomByDelta()', function() {
it('changes view resolution', function() { it('changes view resolution', function() {
+91
View File
@@ -44,4 +44,95 @@ describe('ol.interaction.Pointer', function() {
}); });
describe('event handlers', function() {
let handleDownCalled, handleDragCalled, handleMoveCalled, handleUpCalled;
const flagHandleDown = function() {
handleDownCalled = true;
};
const flagHandleDrag = function() {
handleDragCalled = true;
};
const flagHandleMove = function() {
handleMoveCalled = true;
};
const flagHandleUp = function() {
handleUpCalled = true;
};
class MockPointerInteraction extends PointerInteraction {
constructor() {
super(...arguments);
}
handleDownEvent(mapBrowserEvent) {
flagHandleDown();
return super.handleDownEvent(mapBrowserEvent);
}
handleDragEvent(mapBrowserEvent) {
flagHandleDrag();
}
handleMoveEvent(mapBrowserEvent) {
flagHandleMove();
}
handleUpEvent(mapBrowserEvent) {
flagHandleUp();
return super.handleUpEvent(mapBrowserEvent);
}
}
beforeEach(function() {
handleDownCalled = false;
handleDragCalled = false;
handleMoveCalled = false;
handleUpCalled = false;
});
it('has default event handlers', function() {
const interaction = new PointerInteraction({});
expect(interaction.handleDownEvent()).to.be(false);
expect(interaction.handleUpEvent()).to.be(false);
});
it('allows event handler overrides via options', function() {
const interaction = new PointerInteraction({
handleDownEvent: flagHandleDown,
handleDragEvent: flagHandleDrag,
handleMoveEvent: flagHandleMove,
handleUpEvent: flagHandleUp
});
interaction.handleDownEvent();
expect(handleDownCalled).to.be(true);
interaction.handleDragEvent();
expect(handleDragCalled).to.be(true);
interaction.handleMoveEvent();
expect(handleMoveCalled).to.be(true);
interaction.handleUpEvent();
expect(handleUpCalled).to.be(true);
});
it('allows event handler overrides via class extension', function() {
const interaction = new MockPointerInteraction({});
interaction.handleDownEvent();
expect(handleDownCalled).to.be(true);
interaction.handleDragEvent();
expect(handleDragCalled).to.be(true);
interaction.handleMoveEvent();
expect(handleMoveCalled).to.be(true);
interaction.handleUpEvent();
expect(handleUpCalled).to.be(true);
});
});
}); });
+8 -8
View File
@@ -5,7 +5,7 @@ import View from '../../../../src/ol/View.js';
import Circle from '../../../../src/ol/geom/Circle.js'; import Circle from '../../../../src/ol/geom/Circle.js';
import Point from '../../../../src/ol/geom/Point.js'; import Point from '../../../../src/ol/geom/Point.js';
import LineString from '../../../../src/ol/geom/LineString.js'; import LineString from '../../../../src/ol/geom/LineString.js';
import Snap, {handleEvent} from '../../../../src/ol/interaction/Snap.js'; import Snap from '../../../../src/ol/interaction/Snap.js';
describe('ol.interaction.Snap', function() { describe('ol.interaction.Snap', function() {
@@ -67,7 +67,7 @@ describe('ol.interaction.Snap', function() {
coordinate: [0, 0], coordinate: [0, 0],
map: map map: map
}; };
handleEvent.call(snapInteraction, event); snapInteraction.handleEvent(event);
// check that the coordinate is in XY and not XYZ // check that the coordinate is in XY and not XYZ
expect(event.coordinate).to.eql([0, 0]); expect(event.coordinate).to.eql([0, 0]);
}); });
@@ -86,7 +86,7 @@ describe('ol.interaction.Snap', function() {
coordinate: [7, 4], coordinate: [7, 4],
map: map map: map
}; };
handleEvent.call(snapInteraction, event); snapInteraction.handleEvent(event);
expect(event.coordinate).to.eql([7, 0]); expect(event.coordinate).to.eql([7, 0]);
}); });
@@ -104,7 +104,7 @@ describe('ol.interaction.Snap', function() {
coordinate: [7, 4], coordinate: [7, 4],
map: map map: map
}; };
handleEvent.call(snapInteraction, event); snapInteraction.handleEvent(event);
expect(event.coordinate).to.eql([10, 0]); expect(event.coordinate).to.eql([10, 0]);
}); });
@@ -121,7 +121,7 @@ describe('ol.interaction.Snap', function() {
coordinate: [5, 5], coordinate: [5, 5],
map: map map: map
}; };
handleEvent.call(snapInteraction, event); snapInteraction.handleEvent(event);
expect(event.coordinate[0]).to.roughlyEqual(Math.sin(Math.PI / 4) * 10, 1e-10); expect(event.coordinate[0]).to.roughlyEqual(Math.sin(Math.PI / 4) * 10, 1e-10);
expect(event.coordinate[1]).to.roughlyEqual(Math.sin(Math.PI / 4) * 10, 1e-10); expect(event.coordinate[1]).to.roughlyEqual(Math.sin(Math.PI / 4) * 10, 1e-10);
@@ -143,7 +143,7 @@ describe('ol.interaction.Snap', function() {
coordinate: [7, 4], coordinate: [7, 4],
map: map map: map
}; };
handleEvent.call(snapInteraction, event); snapInteraction.handleEvent(event);
expect(event.coordinate).to.eql([10, 0]); expect(event.coordinate).to.eql([10, 0]);
}); });
@@ -163,7 +163,7 @@ describe('ol.interaction.Snap', function() {
coordinate: [7, 4], coordinate: [7, 4],
map: map map: map
}; };
handleEvent.call(snapInteraction, event); snapInteraction.handleEvent(event);
expect(event.coordinate).to.eql([10, 0]); expect(event.coordinate).to.eql([10, 0]);
}); });
@@ -186,7 +186,7 @@ describe('ol.interaction.Snap', function() {
coordinate: [7, 4], coordinate: [7, 4],
map: map map: map
}; };
handleEvent.call(snapInteraction, event); snapInteraction.handleEvent(event);
expect(event.coordinate).to.eql([10, 0]); expect(event.coordinate).to.eql([10, 0]);
}); });