├── README.md ├── Leaflet.LimitZoom.js └── Leaflet.ContinuousZoom.js /README.md: -------------------------------------------------------------------------------- 1 | # Miss some zoom levels for your tiles? 2 | 3 | That's not a problem with those Leaflet plugins! Your users won't even notice the absense. 4 | See [this map](http://zverik.github.io/Leaflet.LimitZoom/) for a demo. 5 | 6 | ## Leaflet.LimitZoom 7 | 8 | Does not allow selecting zoom levels that are not in a predefined list. 9 | Include the js file and add `zooms: [1, 5, 8, 14]` option to your `L.Map` object, 10 | with zooms of your choosing. 11 | 12 | ## Leaflet.ContinuousZoom 13 | 14 | Allows restricting `L.TileLayer` zoom levels to a predefined list, while 15 | not limiting map zooming functionality. Missing levels are interpolated from 16 | previous, or a minimal existing zoom level. Be careful: set `minZoom` option 17 | to the minimal native zoom, or number of tile request would be enormous. 18 | 19 | To use, include the js file and add `nativeZooms: [2,5,8]` option to a `L.TileLayer` 20 | object, with zooms you have. 21 | 22 | ## Author and License 23 | 24 | Those plugins were written by Ilya Zverev and published under WTFPL license. 25 | -------------------------------------------------------------------------------- /Leaflet.LimitZoom.js: -------------------------------------------------------------------------------- 1 | // Limit leaflet map zoom to a list of variants 2 | // Written by Ilya Zverev, licensed WTFPL 3 | 4 | L.Map.mergeOptions({ 5 | zooms: [] // array of integers 6 | }); 7 | 8 | L.Map.include({ 9 | _limitZoom: function (zoom) { 10 | var zooms = this.options.zooms; 11 | if (!zooms || !('length' in zooms) || !zooms.length) { 12 | var min = this.getMinZoom(), 13 | max = this.getMaxZoom(), 14 | snap = L.Browser.any3d ? this.options.zoomSnap : 1; 15 | if (snap) { 16 | zoom = Math.round(zoom / snap) * snap; 17 | } 18 | return Math.max(min, Math.min(max, zoom)); 19 | } else { 20 | var z, d = 100, i, dist; 21 | var dz = -1, dd = 100, dir = zoom - this._zoom; 22 | var snap = L.Browser.any3d ? this.options.zoomSnap : 1; 23 | if (snap) { 24 | zoom = Math.round(zoom / snap) * snap; 25 | } 26 | for (i = 0; i < zooms.length; i++) { 27 | dist = Math.abs(zooms[i] - zoom); 28 | if (dist < d) { 29 | z = zooms[i]; 30 | d = dist; 31 | } 32 | if (dir * (zooms[i] - this._zoom) > 0 && dist < dd) { 33 | dz = zooms[i]; 34 | dd = dist; 35 | } 36 | } 37 | return dz < 0 ? z : dz; 38 | } 39 | } 40 | }); 41 | -------------------------------------------------------------------------------- /Leaflet.ContinuousZoom.js: -------------------------------------------------------------------------------- 1 | // Fill in missing zoom levels of a tile layer with scaled previous zooms. 2 | // Written by Ilya Zverev, licensed WTFPL 3 | 4 | L.TileLayer.mergeOptions({ 5 | nativeZooms: [] // array of integers 6 | }); 7 | 8 | L.TileLayer.addInitHook(function () { 9 | var opt = this.options, 10 | zooms = opt.nativeZooms; 11 | if( zooms && zooms.length > 0 ) { 12 | var minZoom = 100, i; 13 | for (i = 0; i < zooms.length; i++) 14 | if (zooms[i] < minZoom) 15 | minZoom = zooms[i]; 16 | opt.minZoom = Math.max(opt.minZoom, minZoom - 1); 17 | } 18 | }); 19 | 20 | L.TileLayer.include({ 21 | getTileSize: function () { 22 | var map = this._map, 23 | tileSize = L.GridLayer.prototype.getTileSize.call(this), 24 | zoom = this._tileZoom + this.options.zoomOffset, 25 | nativeZoom = this._mapNativeZoom(zoom); 26 | 27 | return nativeZoom == zoom ? tileSize : 28 | tileSize.divideBy(map.getZoomScale(nativeZoom, zoom)).round(); 29 | }, 30 | 31 | _getZoomForUrl: function () { 32 | var zoom = this._tileZoom, 33 | maxZoom = this.options.maxZoom, 34 | zoomReverse = this.options.zoomReverse, 35 | zoomOffset = this.options.zoomOffset; 36 | 37 | if (zoomReverse) { 38 | zoom = maxZoom - zoom; 39 | } 40 | 41 | zoom += zoomOffset; 42 | 43 | return this._mapNativeZoom(zoom); 44 | }, 45 | 46 | _mapNativeZoom: function (zoom) { 47 | var zooms = this.options.nativeZooms, 48 | minNativeZoom = this.options.minNativeZoom, 49 | maxNativeZoom = this.options.maxNativeZoom; 50 | 51 | if (zooms && zooms.length > 0) { 52 | var prevZoom = -1, minZoom = 100, i; 53 | for (i = 0; i < zooms.length; i++) { 54 | if( zooms[i] <= zoom && zooms[i] > prevZoom ) 55 | prevZoom = zooms[i]; 56 | if( zooms[i] < minZoom ) 57 | minZoom = zooms[i]; 58 | } 59 | zoom = prevZoom < 0 ? minZoom : prevZoom; 60 | } else if (maxNativeZoom !== null && zoom > maxNativeZoom) { 61 | zoom = maxNativeZoom; 62 | } else if (minNativeZoom !== null && zoom < minNativeZoom) { 63 | zoom = minNativeZoom; 64 | } 65 | return zoom; 66 | } 67 | }); 68 | --------------------------------------------------------------------------------