MinedMap/viewer/MinedMap.js

223 lines
4.7 KiB
JavaScript

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 <a href="http://git.universe-factory.net/MinedMap/">MinedMap</a>';
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 + '&nbsp;&nbsp;&nbsp;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 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;
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 zoom = map.getZoom(),
center = map.getCenter(),
x = Math.round(center.lng),
z = Math.round(-center.lat),
ret = '#x='+x+'&z='+z+'&zoom='+zoom;
if (map.hasLayer(lightLayer))
ret += '&light=1';
return ret;
};
var updateHash = function () {
window.location.hash = makeHash();
};
map.on('moveend', updateHash);
map.on('zoomend', updateHash);
map.on('layeradd', updateHash);
map.on('layerremove', updateHash);
window.onhashchange = function () {
if (window.location.hash == makeHash())
return;
var args = parseHash(),
center = map.getCenter(),
zoom = parseInt(args['zoom']),
x = parseFloat(args['x']),
z = parseFloat(args['z']),
light = parseInt(args['light']);
if (isNaN(zoom))
zoom = map.getZoom();
if (isNaN(x))
x = center.lng;
if (isNaN(z))
z = -center.lat;
map.setView([-z, x], zoom);
if (light)
map.addLayer(lightLayer);
else
map.removeLayer(lightLayer);
};
};
xhr.open('GET', 'data/info.json', true);
xhr.send();
}