1 2L.MagnifyingGlass = L.Layer.extend({ 3 options: { 4 radius: 100, 5 zoomOffset: 3, 6 layers: [ ], 7 fixedPosition: false, 8 latLng: [0, 0], 9 fixedZoom: -1 10 }, 11 12 initialize: function(options) { 13 L.Util.setOptions(this, options); 14 this._fixedZoom = (this.options.fixedZoom != -1); 15 this._mainMap = null; 16 this._glassMap = null; 17 }, 18 19 getMap: function(){ 20 return this._glassMap; 21 }, 22 23 _createMiniMap: function(elt) { 24 return new L.Map(elt, { 25 layers: this.options.layers, 26 zoom: this._getZoom(), 27 maxZoom: this._mainMap.getMaxZoom(), 28 minZoom: this._mainMap.getMinZoom(), 29 crs: this._mainMap.options.crs, 30 fadeAnimation: false, 31 // disable every controls and interaction means 32 attributionControl: false, 33 zoomControl: false, 34 boxZoom: false, 35 touchZoom: false, 36 scrollWheelZoom: false, 37 doubleClickZoom: false, 38 dragging: false, 39 keyboard: false, 40 }); 41 }, 42 43 _getZoom: function() { 44 return (this._fixedZoom) ? 45 this.options.fixedZoom : 46 this._mainMap.getZoom() + this.options.zoomOffset; 47 }, 48 49 _updateZoom: function() { 50 this._glassMap.setZoom(this._getZoom()); 51 }, 52 53 setRadius: function(radius) { 54 this.options.radius = radius; 55 if(this._wrapperElt) { 56 this._wrapperElt.style.width = this.options.radius * 2 + 'px'; 57 this._wrapperElt.style.height = this.options.radius * 2 + 'px'; 58 } 59 }, 60 61 setLatLng: function(latLng) { 62 this.options.latLng = latLng; 63 this._update(latLng); 64 }, 65 66 _updateFromMouse: function(evt) { 67 this._update(evt.latlng, evt.layerPoint); 68 }, 69 70 _updateFixed: function() { 71 this._update(this.options.latLng); 72 }, 73 74 _update: function(latLng, layerPoint) { 75 // update mini map view, forcing no animation 76 this._glassMap.setView(latLng, this._getZoom(), { 77 pan : { animate: false } 78 }); 79 80 // update the layer element position on the main map, 81 // using the one provided or reprojecting it 82 layerPoint = layerPoint || this._mainMap.latLngToLayerPoint(latLng); 83 this._wrapperElt.style.left = layerPoint.x - this.options.radius + 'px'; 84 this._wrapperElt.style.top = layerPoint.y - this.options.radius + 'px'; 85 }, 86 87 /** 88 As defined by ILayer 89 */ 90 onAdd: function(map) { 91 this._mainMap = map; 92 // create a wrapper element and a container for the map inside it 93 this._wrapperElt = L.DomUtil.create('div', 'leaflet-magnifying-glass'); 94 var glassMapElt = L.DomUtil.create('div', '', this._wrapperElt); 95 // Webkit border-radius clipping workaround (see CSS) 96 if(L.Browser.webkit) 97 L.DomUtil.addClass(glassMapElt, 'leaflet-magnifying-glass-webkit'); 98 // build the map 99 this._glassMap = this._createMiniMap(glassMapElt); 100 101 // forward some DOM events as Leaflet events 102 L.DomEvent.addListener(this._wrapperElt, 'click', this._fireClick, this); 103 104 var opts = this.options; 105 106 this.setRadius(opts.radius); 107 this.setLatLng(opts.latLng); 108 109 this._glassMap.whenReady(function() { 110 if(opts.fixedPosition) { 111 this._mainMap.on('zoomend', this._updateFixed, this); 112 // for now, hide the elements during zoom transitions 113 L.DomUtil.addClass(this._wrapperElt, ('leaflet-zoom-hide')); 114 } else { 115 this._mainMap.on('mousemove', this._updateFromMouse, this); 116 if(!this._fixedZoom) { 117 this._mainMap.on('zoomend', this._updateZoom, this); 118 } 119 } 120 }, this); 121 122 // add the magnifying glass as a layer to the top-most pane 123 map.getPanes().popupPane.appendChild(this._wrapperElt); 124 125 // needed after the element has been added, otherwise tile loading is messy 126 this._glassMap.invalidateSize(); 127 128 return this; 129 }, 130 131 _fireClick: function(domMouseEvt) { 132 this.fire('click', domMouseEvt); 133 L.DomEvent.stopPropagation(domMouseEvt); 134 }, 135 136 /** 137 As defined by ILayer 138 */ 139 onRemove: function(map) { 140 map.off('viewreset', this._updateFixed, this); 141 map.off('mousemove', this._updateFromMouse, this); 142 map.off('zoomend', this._updateZoom, this); 143 // layers must be explicitely removed before map destruction, 144 // otherwise they can't be reused if the mg is re-added 145 for(var i=0, l=this.options.layers.length; i<l; i++) { 146 this._glassMap.removeLayer(this.options.layers[i]); 147 } 148 this._glassMap.remove(); 149 L.DomEvent.removeListener(this._wrapperElt, 'click', this._fireClick); 150 map.getPanes().popupPane.removeChild(this._wrapperElt); 151 this._mainMap = null; 152 153 return this; 154 } 155}); 156 157L.magnifyingGlass = function (options) { 158 return new L.MagnifyingGlass(options); 159};
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.