var MinedMapLayer = L.GridLayer.extend({ initialize: function (mipmaps, layer) { this.mipmaps = mipmaps; this.layer = layer; this.zoomOffset = L.Browser.retina ? 1 : 0; this.options.attribution = 'Generated by MinedMap'; if (!L.Browser.android) { this.on('tileunload', this._onTileRemove); } }, createTile: function (coords, done) { var tile = document.createElement('img'); tile.onload = L.bind(this._tileOnLoad, this, done, tile); tile.onerror = L.bind(this._tileOnError, this, done, tile); tile.alt = ''; var z = -(coords.z + this.zoomOffset); if (z < 0) z = 0; var mipmap = this.mipmaps[z]; if (coords.x >= mipmap.info.minX && coords.x <= mipmap.info.maxX && coords.y >= mipmap.info.minZ && coords.y <= mipmap.info.maxZ && mipmap.regions[coords.y-mipmap.info.minZ][coords.x-mipmap.info.minX]) tile.src = 'data/'+this.layer+'/'+z+'/r.'+coords.x+'.'+coords.y+'.png'; if (z == 0) L.DomUtil.addClass(tile, 'overzoomed'); return tile; }, _tileOnLoad: function (done, tile) { done(null, tile); }, _tileOnError: function (done, tile, e) { done(e, tile); }, _getTileSize: function () { var map = this._map, zoom = map.getZoom() + this.zoomOffset; var base = (L.Browser.retina ? 256 : 512); if (zoom > 0) return Math.round(map.getZoomScale(zoom, 0) * base); else return base; }, _onTileRemove: function (e) { e.tile.onload = null; e.tile.src = L.Util.emptyImageUrl; }, _abortLoading: function () { var i, tile; for (i in this._tiles) { tile = this._tiles[i].el; tile.onload = L.Util.falseFn; tile.onerror = L.Util.falseFn; if (!tile.complete) { tile.src = L.Util.emptyImageUrl; L.DomUtil.remove(tile); } } } }); var CoordControl = L.Control.extend({ initialize: function () { this.options.position = 'bottomleft'; }, onAdd: function (map) { this._container = L.DomUtil.create('div', 'leaflet-control-attribution'); return this._container; }, update: function (x, z) { if (!this._map) { return; } this._container.innerHTML = 'X: ' + x + '   Z: ' + z; } }); var parseHash = function () { var args = {}; if (window.location.hash) { var parts = window.location.hash.substr(1).split('&'); for (var i = 0; i < parts.length; i++) { var key_value = parts[i].split('='); var key = key_value[0], value = key_value.slice(1).join('='); args[key] = value; } } return args; } window.createMap = function () { var xhr = new XMLHttpRequest(); xhr.onload = function () { var res = JSON.parse(this.responseText), mipmaps = res.mipmaps, spawn = res.spawn; var x, z, zoom, light; var updateParams = function () { var args = parseHash(); zoom = parseInt(args['zoom']); x = parseFloat(args['x']); z = parseFloat(args['z']); light = parseInt(args['light']); if (isNaN(zoom)) zoom = 0; if (isNaN(x)) x = spawn.x; if (isNaN(z)) z = spawn.z; }; updateParams(); var map = L.map('map', { center: [-z, x], zoom: zoom, minZoom: -(mipmaps.length-1), maxZoom: 3, crs: L.CRS.Simple, maxBounds: [ [-512*(mipmaps[0].info.maxZ+1), 512*mipmaps[0].info.minX], [-512*mipmaps[0].info.minZ, 512*(mipmaps[0].info.maxX+1)], ], }); var mapLayer = new MinedMapLayer(mipmaps, 'map'); var lightLayer = new MinedMapLayer(mipmaps, 'light'); mapLayer.addTo(map); if (light) map.addLayer(lightLayer); var overlayMaps = { "Illumination": lightLayer, }; L.control.layers({}, overlayMaps).addTo(map); var coordControl = new CoordControl(); coordControl.addTo(map); map.on('mousemove', function(e) { coordControl.update(Math.round(e.latlng.lng), Math.round(-e.latlng.lat)); }); var makeHash = function () { var ret = '#x='+x+'&z='+z; if (zoom != 0) ret += '&zoom='+zoom; if (map.hasLayer(lightLayer)) ret += '&light=1'; return ret; }; var updateHash = function () { window.location.hash = makeHash(); }; var refreshHash = function () { zoom = map.getZoom(); center = map.getCenter(); x = Math.round(center.lng); z = Math.round(-center.lat); updateHash(); } updateHash(); map.on('moveend', refreshHash); map.on('zoomend', refreshHash); map.on('layeradd', refreshHash); map.on('layerremove', refreshHash); window.onhashchange = function () { if (window.location.hash == makeHash()) return; updateParams(); map.setView([-z, x], zoom); if (light) map.addLayer(lightLayer); else map.removeLayer(lightLayer); updateHash(); }; }; xhr.open('GET', 'data/info.json', true); xhr.send(); }