forked from Garde-Studios/minecraft-docker-server
172 lines
5.5 KiB
JavaScript
172 lines
5.5 KiB
JavaScript
|
import { Sidebar } from "./Sidebar.js";
|
||
|
import { PlayerList } from "./PlayerList.js";
|
||
|
import { WorldList } from "./WorldList.js";
|
||
|
import { UICoordinates } from "./UICoordinates.js";
|
||
|
import { UILink } from "./UILink.js";
|
||
|
import { LayerControl } from "./LayerControl.js";
|
||
|
|
||
|
class SquaremapMap {
|
||
|
constructor() {
|
||
|
this.map = L.map("map", {
|
||
|
crs: L.CRS.Simple,
|
||
|
center: [0, 0],
|
||
|
attributionControl: false,
|
||
|
preferCanvas: true,
|
||
|
noWrap: true
|
||
|
})
|
||
|
.on('overlayadd', (e) => {
|
||
|
this.layerControl.showLayer(e.layer);
|
||
|
})
|
||
|
.on('overlayremove', (e) => {
|
||
|
this.layerControl.hideLayer(e.layer);
|
||
|
})
|
||
|
.on('click', (e) => {
|
||
|
this.playerList.followPlayerMarker(null);
|
||
|
})
|
||
|
.on('dblclick', (e) => {
|
||
|
this.playerList.followPlayerMarker(null);
|
||
|
});
|
||
|
|
||
|
this.tick_count = 1;
|
||
|
|
||
|
this.layerControl = new LayerControl();
|
||
|
|
||
|
this.init();
|
||
|
}
|
||
|
loop() {
|
||
|
if (document.visibilityState === 'visible') {
|
||
|
this.tick();
|
||
|
this.tick_count++;
|
||
|
}
|
||
|
setTimeout(() => this.loop(), 1000);
|
||
|
}
|
||
|
tick() {
|
||
|
// tick player tracker
|
||
|
this.playerList.tick();
|
||
|
// tick world
|
||
|
this.worldList.curWorld.tick();
|
||
|
}
|
||
|
init() {
|
||
|
this.getJSON("tiles/settings.json", (json) => {
|
||
|
this.layerControl.init();
|
||
|
|
||
|
this.title = json.ui.title;
|
||
|
this.sidebar = new Sidebar(json.ui.sidebar, this.getUrlParam("show_sidebar", "true") === "true");
|
||
|
this.playerList = new PlayerList(json.ui.sidebar);
|
||
|
this.worldList = new WorldList(json.worlds);
|
||
|
this.coordinates = new UICoordinates(json.ui.coordinates, this.getUrlParam("show_coordinates", "true") === "true");
|
||
|
this.uiLink = new UILink(json.ui.link, this.getUrlParam("show_link_button", "true") === "true");
|
||
|
|
||
|
this.showControls = this.getUrlParam("show_controls", "true") === "true"
|
||
|
if (!this.showControls) {
|
||
|
let controlLayers = document.getElementsByClassName('leaflet-top leaflet-left');
|
||
|
controlLayers[0].style.display = "none";
|
||
|
}
|
||
|
|
||
|
this.worldList.loadInitialWorld(json, (world) => {
|
||
|
this.loop();
|
||
|
this.centerOn(
|
||
|
this.getUrlParam("x", world.spawn.x),
|
||
|
this.getUrlParam("z", world.spawn.z),
|
||
|
this.getUrlParam("zoom", world.zoom.def));
|
||
|
});
|
||
|
|
||
|
});
|
||
|
}
|
||
|
centerOn(x, z, zoom) {
|
||
|
this.map.setView(this.toLatLng(x, z), zoom);
|
||
|
this.uiLink.update();
|
||
|
return this.map;
|
||
|
}
|
||
|
toLatLng(x, z) {
|
||
|
return L.latLng(this.pixelsToMeters(-z), this.pixelsToMeters(x));
|
||
|
//return this.map.unproject([x, z], this.worldList.curWorld.zoom.max);
|
||
|
}
|
||
|
toPoint(latlng) {
|
||
|
return L.point(this.metersToPixels(latlng.lng), this.metersToPixels(-latlng.lat));
|
||
|
//return this.map.project(latlng, this.worldList.curWorld.zoom.max);
|
||
|
}
|
||
|
pixelsToMeters(num) {
|
||
|
return num * this.scale;
|
||
|
}
|
||
|
metersToPixels(num) {
|
||
|
return num / this.scale;
|
||
|
}
|
||
|
setScale(zoom) {
|
||
|
this.scale = (1 / Math.pow(2, zoom));
|
||
|
// store this on map for ellipse
|
||
|
this.map.options.scale = this.scale;
|
||
|
}
|
||
|
createElement(tag, id, parent) {
|
||
|
const element = document.createElement(tag);
|
||
|
element.id = id;
|
||
|
element.parent = parent;
|
||
|
return element;
|
||
|
}
|
||
|
createTextElement(tag, text) {
|
||
|
const element = document.createElement(tag);
|
||
|
element.appendChild(document.createTextNode(text));
|
||
|
return element;
|
||
|
}
|
||
|
getJSON(url, fn) {
|
||
|
fetch(url, {cache: "no-store"})
|
||
|
.then(async res => {
|
||
|
if (res.ok) {
|
||
|
fn(await res.json());
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
getUrlParam(query, def) {
|
||
|
const url = window.location.search.substring(1);
|
||
|
const vars = url.split('&');
|
||
|
for (let i = 0; i < vars.length; i++) {
|
||
|
const param = vars[i].split('=');
|
||
|
if (param[0] === query) {
|
||
|
const value = param[1] === undefined ? '' : decodeURIComponent(param[1]);
|
||
|
return value === '' ? def : value;
|
||
|
}
|
||
|
}
|
||
|
return def;
|
||
|
}
|
||
|
getUrlFromView() {
|
||
|
const center = this.toPoint(this.map.getCenter());
|
||
|
const zoom = this.map.getZoom();
|
||
|
const x = Math.floor(center.x);
|
||
|
const z = Math.floor(center.y);
|
||
|
const following = this.playerList.following ? `&uuid=${this.playerList.following}` : '';
|
||
|
let link = `?world=${this.worldList.curWorld.name}&zoom=${zoom}&x=${x}&z=${z}${following}`;
|
||
|
if (!this.showControls) {
|
||
|
link += "&show_controls=false"
|
||
|
}
|
||
|
if (!this.uiLink.showLinkButton) {
|
||
|
link += "&show_link_button=false"
|
||
|
}
|
||
|
if (!this.coordinates.showCoordinates) {
|
||
|
link += "&show_coordinates=false"
|
||
|
}
|
||
|
if (!this.sidebar.showSidebar) {
|
||
|
link += "&show_sidebar=false"
|
||
|
}
|
||
|
return link
|
||
|
}
|
||
|
updateBrowserUrl(url) {
|
||
|
window.history.replaceState(null, "", url);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
export const P = new SquaremapMap();
|
||
|
|
||
|
|
||
|
// https://stackoverflow.com/a/3955096
|
||
|
Array.prototype.remove = function() {
|
||
|
var what, a = arguments, L = a.length, ax;
|
||
|
while (L && this.length) {
|
||
|
what = a[--L];
|
||
|
while ((ax = this.indexOf(what)) !== -1) {
|
||
|
this.splice(ax, 1);
|
||
|
}
|
||
|
}
|
||
|
return this;
|
||
|
};
|