UNPKG

maplair

Version:

JavaScript library for mobile-friendly interactive maps

107 lines (106 loc) • 3.69 kB
import { setOptions } from "../core/Util.js"; import { Point } from "../geometry/Point.js"; import { getPointers } from "./DomEvent.PointerEvents.js"; import { off, on } from "./DomEvent.js"; import { disableImageDrag, disableTextSelection, enableImageDrag, enableTextSelection, getPosition, getScale, getSizedParentNode, preventOutline, setPosition } from "./DomUtil.js"; import { Evented } from "../core/Events.js"; //#region src/dom/Draggable.js var Draggable = class Draggable extends Evented { static { this.setDefaultOptions({ clickTolerance: 3 }); } constructor(element, dragStartTarget, preventOutline, options) { super(); setOptions(this, options); this._element = element; this._dragStartTarget = dragStartTarget ?? element; this._preventOutline = preventOutline; this.callInitHooks(Draggable); } enable() { if (this._enabled) return; on(this._dragStartTarget, "pointerdown", this._onDown, this); this._enabled = true; } disable() { if (!this._enabled) return; if (Draggable._dragging === this) this.finishDrag(true); off(this._dragStartTarget, "pointerdown", this._onDown, this); this._enabled = false; this._moved = false; } _onDown(e) { this._moved = false; if (this._element.classList.contains("maplair-zoom-anim")) return; if (getPointers().length !== 1) { if (Draggable._dragging === this) this.finishDrag(); return; } if (Draggable._dragging || e.shiftKey || e.button !== 0 && e.pointerType !== "touch") return; Draggable._dragging = this; if (this._preventOutline) preventOutline(this._element); disableImageDrag(); disableTextSelection(); if (this._moving) return; this.fire("down"); const sizedParent = getSizedParentNode(this._element); this._startPoint = new Point(e.clientX, e.clientY); this._startPos = getPosition(this._element); this._parentScale = getScale(sizedParent); on(this._dragStartTarget, "pointermove", this._onMove, this); on(this._dragStartTarget, "pointerup pointercancel", this._onUp, this); } _onMove(e) { if (getPointers().length > 1) { this._moved = true; return; } const offset = new Point(e.clientX, e.clientY)._subtract(this._startPoint); if (!offset.x && !offset.y) return; if (Math.abs(offset.x) + Math.abs(offset.y) < this.options.clickTolerance) return; offset.x /= this._parentScale.x; offset.y /= this._parentScale.y; if (e.cancelable) e.preventDefault(); if (!this._moved) { this.fire("dragstart"); this._moved = true; this._element.ownerDocument.body.classList.add("maplair-dragging"); this._lastTarget = e.target ?? e.srcElement; this._lastTarget.classList.add("maplair-drag-target"); } this._newPos = this._startPos.add(offset); this._moving = true; this._lastEvent = e; this._updatePosition(); } _updatePosition() { const e = { originalEvent: this._lastEvent }; this.fire("predrag", e); setPosition(this._element, this._newPos); this.fire("drag", e); } _onUp() { this.finishDrag(); } finishDrag(noInertia) { this._element.ownerDocument.body.classList.remove("maplair-dragging"); if (this._lastTarget) { this._lastTarget.classList.remove("maplair-drag-target"); this._lastTarget = null; } off(this._dragStartTarget, "pointermove", this._onMove, this); off(this._dragStartTarget, "pointerup pointercancel", this._onUp, this); enableImageDrag(); enableTextSelection(); const fireDragend = this._moved && this._moving; this._moving = false; Draggable._dragging = false; if (fireDragend) this.fire("dragend", { noInertia, distance: this._newPos.distanceTo(this._startPos) }); } }; //#endregion export { Draggable }; //# sourceMappingURL=Draggable.js.map