1// Following https://github.com/Leaflet/Leaflet/blob/master/PLUGIN-GUIDE.md 2(function (factory, window) { 3 4 // define an AMD module that relies on 'leaflet' 5 if (typeof define === 'function' && define.amd) { 6 define(['leaflet'], factory); 7 8 // define a Common JS module that relies on 'leaflet' 9 } else if (typeof exports === 'object') { 10 module.exports = factory(require('leaflet')); 11 } 12 13 // attach your plugin to the global 'L' variable 14 if (typeof window !== 'undefined' && window.L) { 15 window.L.Control.MiniMap = factory(L); 16 window.L.control.minimap = function (layer, options) { 17 return new window.L.Control.MiniMap(layer, options); 18 }; 19 } 20}(function (L) { 21 22 var MiniMap = L.Control.extend({ 23 24 includes: L.Evented ? L.Evented.prototype : L.Mixin.Events, 25 26 options: { 27 position: 'bottomright', 28 toggleDisplay: false, 29 zoomLevelOffset: -5, 30 zoomLevelFixed: false, 31 centerFixed: false, 32 zoomAnimation: false, 33 autoToggleDisplay: false, 34 minimized: false, 35 width: 150, 36 height: 150, 37 collapsedWidth: 19, 38 collapsedHeight: 19, 39 aimingRectOptions: {color: '#ff7800', weight: 1, interactive: false}, 40 shadowRectOptions: {color: '#000000', weight: 1, interactive: false, opacity: 0, fillOpacity: 0}, 41 strings: {hideText: 'Hide MiniMap', showText: 'Show MiniMap'}, 42 mapOptions: {} // Allows definition / override of Leaflet map options. 43 }, 44 45 // layer is the map layer to be shown in the minimap 46 initialize: function (layer, options) { 47 L.Util.setOptions(this, options); 48 // Make sure the aiming rects are non-clickable even if the user tries to set them clickable (most likely by forgetting to specify them false) 49 this.options.aimingRectOptions.interactive = false; 50 this.options.shadowRectOptions.interactive = false; 51 this._layer = layer; 52 }, 53 54 onAdd: function (map) { 55 56 this._mainMap = map; 57 58 // Creating the container and stopping events from spilling through to the main map. 59 this._container = L.DomUtil.create('div', 'leaflet-control-minimap'); 60 this._container.style.width = this.options.width + 'px'; 61 this._container.style.height = this.options.height + 'px'; 62 L.DomEvent.disableClickPropagation(this._container); 63 L.DomEvent.on(this._container, 'mousewheel', L.DomEvent.stopPropagation); 64 65 var mapOptions = { 66 attributionControl: false, 67 dragging: !this.options.centerFixed, 68 zoomControl: false, 69 zoomAnimation: this.options.zoomAnimation, 70 autoToggleDisplay: this.options.autoToggleDisplay,
71 touchZoom: this.options.centerFixed ? 'center' : !this._isZoomLevelFixed(), 72 scrollWheelZoom: this.options.centerFixed ? 'center' : !this._isZoomLevelFixed(), 73 doubleClickZoom: this.options.centerFixed ? 'center' : !this._isZoomLevelFixed(), 74 boxZoom: !this._isZoomLevelFixed(), 75 crs: map.options.crs 76 }; 77 mapOptions = L.Util.extend(this.options.mapOptions, mapOptions); // merge with priority of the local mapOptions object. 78 79 this._miniMap = new L.Map(this._container, mapOptions); 80 81 this._miniMap.addLayer(this._layer); 82 83 // These bools are used to prevent infinite loops of the two maps notifying each other that they've moved. 84 this._mainMapMoving = false; 85 this._miniMapMoving = false; 86 87 // Keep a record of this to prevent auto toggling when the user explicitly doesn't want it. 88 this._userToggledDisplay = false; 89 this._minimized = false; 90 91 if (this.options.toggleDisplay) { 92 this._addToggleButton(); 93 } 94 95 this._miniMap.whenReady(L.Util.bind(function () { 96 this._aimingRect = L.rectangle(this._mainMap.getBounds(), this.options.aimingRectOptions).addTo(this._miniMap); 97 this._shadowRect = L.rectangle(this._mainMap.getBounds(), this.options.shadowRectOptions).addTo(this._miniMap); 98 this._mainMap.on('moveend', this._onMainMapMoved, this); 99 this._mainMap.on('move', this._onMainMapMoving, this); 100 this._miniMap.on('movestart', this._onMiniMapMoveStarted, this); 101 this._miniMap.on('move', this._onMiniMapMoving, this); 102 this._miniMap.on('moveend', this._onMiniMapMoved, this); 103 }, this)); 104 105 return this._container; 106 }, 107 108 addTo: function (map) { 109 L.Control.prototype.addTo.call(this, map); 110 111 var center = this.options.centerFixed || this._mainMap.getCenter(); 112 this._miniMap.setView(center, this._decideZoom(true)); 113 this._setDisplay(this.options.minimized); 114 return this; 115 }, 116 117 onRemove: function (map) { 118 this._mainMap.off('moveend', this._onMainMapMoved, this); 119 this._mainMap.off('move', this._onMainMapMoving, this); 120 this._miniMap.off('moveend', this._onMiniMapMoved, this); 121 122 this._miniMap.removeLayer(this._layer); 123 }, 124 125 changeLayer: function (layer) { 126 this._miniMap.removeLayer(this._layer); 127 this._layer = layer; 128 this._miniMap.addLayer(this._layer); 129 }, 130 131 _addToggleButton: function () { 132 this._toggleDisplayButton = this.options.toggleDisplay ? this._createButton( 133 '', this._toggleButtonInitialTitleText(), ('leaflet-control-minimap-toggle-display leaflet-control-minimap-toggle-display-' + 134 this.options.position), this._container, this._toggleDisplayButtonClicked, this) : undefined; 135 136 this._toggleDisplayButton.style.width = this.options.collapsedWidth + 'px'; 137 this._toggleDisplayButton.style.height = this.options.collapsedHeight + 'px'; 138 }, 139 140 _toggleButtonInitialTitleText: function () { 141 if (this.options.minimized) { 142 return this.options.strings.showText; 143 } else { 144 return this.options.strings.hideText; 145 } 146 }, 147 148 _createButton: function (html, title, className, container, fn, context) { 149 var link = L.DomUtil.create('a', className, container); 150 link.innerHTML = html; 151 link.href = '#'; 152 link.title = title; 153 154 var stop = L.DomEvent.stopPropagation; 155 156 L.DomEvent 157 .on(link, 'click', stop) 158 .on(link, 'mousedown', stop) 159 .on(link, 'dblclick', stop) 160 .on(link, 'click', L.DomEvent.preventDefault) 161 .on(link, 'click', fn, context); 162 163 return link; 164 }, 165 166 _toggleDisplayButtonClicked: function () { 167 this._userToggledDisplay = true; 168 if (!this._minimized) { 169 this._minimize(); 170 } else { 171 this._restore(); 172 } 173 }, 174 175 _setDisplay: function (minimize) { 176 if (minimize !== this._minimized) { 177 if (!this._minimized) { 178 this._minimize(); 179 } else { 180 this._restore(); 181 } 182 } 183 }, 184 185 _minimize: function () { 186 // hide the minimap 187 if (this.options.toggleDisplay) { 188 this._container.style.width = this.options.collapsedWidth + 'px'; 189 this._container.style.height = this.options.collapsedHeight + 'px'; 190 this._toggleDisplayButton.className += (' minimized-' + this.options.position); 191 this._toggleDisplayButton.title = this.options.strings.showText; 192 } else { 193 this._container.style.display = 'none'; 194 } 195 this._minimized = true;
196 this._onToggle(); 197 }, 198 199 _restore: function () { 200 if (this.options.toggleDisplay) { 201 this._container.style.width = this.options.width + 'px'; 202 this._container.style.height = this.options.height + 'px'; 203 this._toggleDisplayButton.className = this._toggleDisplayButton.className 204 .replace('minimized-' + this.options.position, ''); 205 this._toggleDisplayButton.title = this.options.strings.hideText; 206 } else { 207 this._container.style.display = 'block'; 208 } 209 this._minimized = false; 210 this._onToggle(); 211 }, 212 213 _onMainMapMoved: function (e) { 214 if (!this._miniMapMoving) { 215 var center = this.options.centerFixed || this._mainMap.getCenter(); 216 217 this._mainMapMoving = true; 218 this._miniMap.setView(center, this._decideZoom(true)); 219 this._setDisplay(this._decideMinimized()); 220 } else { 221 this._miniMapMoving = false; 222 } 223 this._aimingRect.setBounds(this._mainMap.getBounds()); 224 }, 225 226 _onMainMapMoving: function (e) { 227 this._aimingRect.setBounds(this._mainMap.getBounds()); 228 }, 229 230 _onMiniMapMoveStarted: function (e) { 231 if (!this.options.centerFixed) { 232 var lastAimingRect = this._aimingRect.getBounds(); 233 var sw = this._miniMap.latLngToContainerPoint(lastAimingRect.getSouthWest
233()); 234 var ne = this._miniMap.latLngToContainerPoint(lastAimingRect.getNorthEast()); 235 this._lastAimingRectPosition = {sw: sw, ne: ne}; 236 } 237 }, 238 239 _onMiniMapMoving: function (e) { 240 if (!this.options.centerFixed) { 241 if (!this._mainMapMoving && this._lastAimingRectPosition) { 242 this._shadowRect.setBounds(new L.LatLngBounds(this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.sw), this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.ne))); 243 this._shadowRect.setStyle({opacity: 1, fillOpacity: 0.3}); 244 } 245 } 246 }, 247 248 _onMiniMapMoved: function (e) { 249 if (!this._mainMapMoving) { 250 this._miniMapMoving = true; 251 this._mainMap.setView(this._miniMap.getCenter(), this._decideZoom(false)); 252 this._shadowRect.setStyle({opacity: 0, fillOpacity: 0}); 253 } else { 254 this._mainMapMoving = false; 255 } 256 }, 257 258 _isZoomLevelFixed: function () { 259 var zoomLevelFixed = this.options.zoomLevelFixed; 260 return this._isDefined(zoomLevelFixed) && this._isInteger(zoomLevelFixed); 261 }, 262 263 _decideZoom: function (fromMaintoMini) { 264 if (!this._isZoomLevelFixed()) { 265 if (fromMaintoMini) { 266 return this._mainMap.getZoom() + this.options.zoomLevelOffset; 267 } else { 268 var currentDiff = this._miniMap.getZoom() - this._mainMap.getZoom(); 269 var proposedZoom = this._miniMap.getZoom() - this.options.zoomLevelOffset; 270 var toRet; 271 272 if (currentDiff > this.options.zoomLevelOffset && this._mainMap.getZoom() < this._miniMap.getMinZoom() - this.options.zoomLevelOffset) { 273 // This means the miniMap is zoomed out to the minimum zoom level and can't zoom any more. 274 if (this._miniMap.getZoom() > this._lastMiniMapZoom) { 275 // This means the user is trying to zoom in by using the minimap, zoom the main map. 276 toRet = this._mainMap.getZoom() + 1; 277 // Also we cheat and zoom the minimap out again to keep it visually consistent. 278 this._miniMap.setZoom(this._miniMap.getZoom() - 1); 279 } else { 280 // Either the user is trying to zoom out past the mini map's min zoom or has just panned using it, we can't tell the difference. 281 // Therefore, we ignore it! 282 toRet = this._mainMap.getZoom(); 283 } 284 } else { 285 // This is what happens in the majority of cases, and always if you configure the min levels + offset in a sane fashion. 286 toRet = proposedZoom; 287 } 288 this._lastMiniMapZoom = this._miniMap.getZoom(); 289 return toRet; 290 } 291 } else { 292 if (fromMaintoMini) { 293 return this.options.zoomLevelFixed; 294 } else { 295 return this._mainMap.getZoom(); 296 } 297 } 298 }, 299 300 _decideMinimized: function () { 301 if (this._userToggledDisplay) { 302 return this._minimized; 303 } 304 305 if (this.options.autoToggleDisplay) { 306 if (this._mainMap.getBounds().contains(this._miniMap.getBounds())) { 307 return true; 308 } 309 return false; 310 } 311 312 return this._minimized; 313 }, 314 315 _isInteger: function (value) { 316 return typeof value === 'number'; 317 }, 318 319 _isDefined: function (value) { 320 return typeof value !== 'undefined'; 321 }, 322 323 _onToggle: function () { 324 L.Util.requestAnimFrame(function () { 325 L.DomEvent.on(this._container, 'transitionend', this._fireToggleEvents, this); 326 if (!L.Browser.any3d) { 327 L.Util.requestAnimFrame(this._fireToggleEvents, this); 328 } 329 }, this); 330 }, 331 332 _fireToggleEvents: function () { 333 L.DomEvent.off(this._container, 'transitionend', this._fireToggleEvents, this); 334 var data = { minimized: this._minimized }; 335 this.fire(this._minimized ? 'minimize' : 'restore', data); 336 this.fire('toggle', data); 337 } 338 }); 339 340 L.Map.mergeOptions({ 341 miniMapControl: false 342 }); 343 344 L.Map.addInitHook(function () { 345 if (this.options.miniMapControl) { 346 this.miniMapControl = (new MiniMap()).addTo(this); 347 } 348 }); 349 350 return MiniMap; 351 352}, window));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.