/** * L.Map.SelectArea - Area selection tool for leaflet * * @author Alexander Milevski * @see https://github.com/w8r/leaflet-area-select * @license MIT * @preserve */ // UMD !function(t){var o;if("function"==typeof define&&define.amd) // AMD define(["leaflet"],t);else if("undefined"!=typeof module) // Node/CommonJS o=require("leaflet"),module.exports=t(o);else{ // Browser globals if(void 0===window.L)throw new Error("Leaflet must be loaded first");t(window.L)}}(function(a){function t(){return!0} /** * @class L.Map.SelectArea * @extends {L.Map.BoxZoom} */ a.Map.SelectArea=a.Map.BoxZoom.extend({statics:{ /** * @static * @type {String} */ AREA_SELECTED:"areaselected", /** * @static * @type {String} */ AREA_SELECT_START:"areaselectstart", /** * @static * @type {String} */ AREA_SELECTION_TOGGLED:"areaselecttoggled"},options:{shiftKey:!1,ctrlKey:!0,validate:t,autoDisable:!1,cursor:"crosshair"}, /** * @param {L.Map} map * @constructor */ initialize:function(t,o){a.Util.setOptions(this,o||{}),a.Map.BoxZoom.prototype.initialize.call(this,t), /** * @type {Function} */ this._validate=null, /** * @type {Boolean} */ this._moved=!1, /** * @type {Boolean} */ this._autoDisable=!this.options.ctrlKey&&this.options.autoDisable, /** * @type {L.Point} */ this._lastLayerPoint=null, /** * @type {String|Null} */ this._beforeCursor=null,this.setValidate(this.options.validate),this.setAutoDisable(this.options.autoDisable)}, /** * @param {Function=} validate * @return {SelectArea} */ setValidate:function(o){var e=this;return"function"!=typeof o&&(o=t),this._validate=function(t){return o.call(e,t)},this}, /** * @param {Boolean} autoDisable */ setAutoDisable:function(t){this._autoDisable=!!t}, /** * @param {Boolean} on */ setControlKey:function(t){var o=this._enabled;o&&this.disable(),this.options.ctrlKey=!!t,t&&(this.options.shiftKey=!1),o&&this.enable()}, /** * @param {Boolean} on */ setShiftKey:function(t){var o=this._enabled;o&&this.disable(),this.options.shiftKey=!!t,t&&(this.options.ctrlKey=!1),o&&this.enable()}, /** * Disable dragging or zoombox * @param {Function=} validate * @param {Boolean=} autoDisable */ enable:function(t,o){this.options.shiftKey?this._map.boxZoom&&this._map.boxZoom.disable():this.options.ctrlKey||this._map.dragging.disable(),a.Map.BoxZoom.prototype.enable.call(this),this.options.ctrlKey||this._setCursor(),t&&this.setValidate(t),this.setAutoDisable(o),this._map.fire(a.Map.SelectArea.AREA_SELECTION_TOGGLED)}, /** * Re-enable box zoom or dragging */ disable:function(){a.Map.BoxZoom.prototype.disable.call(this),this.options.ctrlKey||this._restoreCursor(),this.options.shiftKey?this._map.boxZoom&&this._map.boxZoom.enable():this._map.dragging.enable(),this._map.fire(a.Map.SelectArea.AREA_SELECTION_TOGGLED)}, /** * Also listen to ESC to cancel interaction * @override */ addHooks:function(){a.Map.BoxZoom.prototype.addHooks.call(this),a.DomEvent.on(document,"keyup",this._onKeyUp,this).on(document,"keydown",this._onKeyPress,this).on(document,"contextmenu",this._onMouseDown,this).on(window,"blur",this._onBlur,this),this._map.on("dragstart",this._onMouseDown,this)}, /** * @override */ removeHooks:function(){a.Map.BoxZoom.prototype.removeHooks.call(this),a.DomEvent.off(document,"keyup",this._onKeyUp,this).off(document,"keydown",this._onKeyPress,this).off(document,"contextmenu",this._onMouseDown,this).off(window,"blur",this._onBlur,this),this._map.off("dragstart",this._onMouseDown,this)}, /** * @override */ _onMouseDown:function(t){if(this._moved=!1,this._lastLayerPoint=null,this.options.shiftKey&&!t.shiftKey||this.options.ctrlKey&&!t.ctrlKey||1!==t.which&&1!==t.button)return!1;a.DomEvent.stop(t);var o=this._map.mouseEventToLayerPoint(t);if(!this._validate(o))return!1;a.DomUtil.disableTextSelection(),a.DomUtil.disableImageDrag(),this._startLayerPoint=o,a.DomEvent.on(document,"mousemove",this._onMouseMove,this).on(document,"mouseup",this._onMouseUp,this).on(document,"keydown",this._onKeyDown,this)}, /** * @override */ _onMouseMove:function(t){this._moved||(this._box=a.DomUtil.create("div","leaflet-zoom-box",this._pane),a.DomUtil.setPosition(this._box,this._startLayerPoint),this._map.fire(a.Map.SelectArea.AREA_SELECT_START));var o,e=this._startLayerPoint,i=this._box,s=this._map.mouseEventToLayerPoint(t),n=s.subtract(e);this._validate(s)&&(this._lastLayerPoint=s,o=new a.Point(Math.min(s.x,e.x),Math.min(s.y,e.y)),a.DomUtil.setPosition(i,o),this._moved=!0, // TODO refactor: remove hardcoded 4 pixels i.style.width=Math.max(0,Math.abs(n.x)-4)+"px",i.style.height=Math.max(0,Math.abs(n.y)-4)+"px")}, /** * General on/off toggle * @param {KeyboardEvent} e */ _onKeyUp:function(t){27===t.keyCode?this._moved&&this._box&&this._finish():this.options.ctrlKey&&(this._restoreCursor(),this._map.dragging.enable())}, /** * Key down listener to enable on ctrl-press * @param {KeyboardEvent} e */ _onKeyPress:function(t){this.options.ctrlKey&&(t.ctrlKey||"dragstart"===t.type)&&null===this._beforeCursor&&(this._setCursor(),this._map.dragging._draggable._onUp(t),// hardcore this._map.dragging.disable())}, /** * Window blur listener to restore state * @param {Event} e */ _onBlur:function(t){this._restoreCursor(),this._map.dragging.enable()}, /** * Set crosshair cursor */ _setCursor:function(){this._beforeCursor=this._container.style.cursor,this._container.style.cursor=this.options.cursor}, /** * Restore status quo cursor */ _restoreCursor:function(){this._container.style.cursor=this._beforeCursor,this._beforeCursor=null}, /** * @override */ _onMouseUp:function(t){this._finish();var o,e=this._map,i=this._lastLayerPoint;// map.mouseEventToLayerPoint(e); i&&!this._startLayerPoint.equals(i)&&(a.DomEvent.stop(t),o=new a.LatLngBounds(e.layerPointToLatLng(this._startLayerPoint),e.layerPointToLatLng(i)), //map.fitBounds(bounds); this._autoDisable?this.disable():this._restoreCursor(),this._moved=!1,a.Util.requestAnimFrame(function(){e.fire(a.Map.SelectArea.AREA_SELECTED,{bounds:o})}))}}), // expose setting a.Map.mergeOptions({selectArea:!1}), // register hook a.Map.addInitHook("addHandler","selectArea",a.Map.SelectArea)});