UNPKG

leaflet

Version:

JavaScript library for mobile-friendly interactive maps

124 lines (95 loc) 2.99 kB
/* * L.Handler.BoxZoom is used to add shift-drag zoom interaction to the map * (zoom to a selected bounding box), enabled by default. */ // @namespace Map // @section Interaction Options L.Map.mergeOptions({ // @option boxZoom: Boolean = true // Whether the map can be zoomed to a rectangular area specified by // dragging the mouse while pressing the shift key. boxZoom: true }); L.Map.BoxZoom = L.Handler.extend({ initialize: function (map) { this._map = map; this._container = map._container; this._pane = map._panes.overlayPane; }, addHooks: function () { L.DomEvent.on(this._container, 'mousedown', this._onMouseDown, this); }, removeHooks: function () { L.DomEvent.off(this._container, 'mousedown', this._onMouseDown, this); }, moved: function () { return this._moved; }, _resetState: function () { this._moved = false; }, _onMouseDown: function (e) { if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; } this._resetState(); L.DomUtil.disableTextSelection(); L.DomUtil.disableImageDrag(); this._startPoint = this._map.mouseEventToContainerPoint(e); L.DomEvent.on(document, { contextmenu: L.DomEvent.stop, mousemove: this._onMouseMove, mouseup: this._onMouseUp, keydown: this._onKeyDown }, this); }, _onMouseMove: function (e) { if (!this._moved) { this._moved = true; this._box = L.DomUtil.create('div', 'leaflet-zoom-box', this._container); L.DomUtil.addClass(this._container, 'leaflet-crosshair'); this._map.fire('boxzoomstart'); } this._point = this._map.mouseEventToContainerPoint(e); var bounds = new L.Bounds(this._point, this._startPoint), size = bounds.getSize(); L.DomUtil.setPosition(this._box, bounds.min); this._box.style.width = size.x + 'px'; this._box.style.height = size.y + 'px'; }, _finish: function () { if (this._moved) { L.DomUtil.remove(this._box); L.DomUtil.removeClass(this._container, 'leaflet-crosshair'); } L.DomUtil.enableTextSelection(); L.DomUtil.enableImageDrag(); L.DomEvent.off(document, { contextmenu: L.DomEvent.stop, mousemove: this._onMouseMove, mouseup: this._onMouseUp, keydown: this._onKeyDown }, this); }, _onMouseUp: function (e) { if ((e.which !== 1) && (e.button !== 1)) { return; } this._finish(); if (!this._moved) { return; } // Postpone to next JS tick so internal click event handling // still see it as "moved". setTimeout(L.bind(this._resetState, this), 0); var bounds = new L.LatLngBounds( this._map.containerPointToLatLng(this._startPoint), this._map.containerPointToLatLng(this._point)); this._map .fitBounds(bounds) .fire('boxzoomend', {boxZoomBounds: bounds}); }, _onKeyDown: function (e) { if (e.keyCode === 27) { this._finish(); } } }); // @section Handlers // @property boxZoom: Handler // Box (shift-drag with mouse) zoom handler. L.Map.addInitHook('addHandler', 'boxZoom', L.Map.BoxZoom);