let map = null; let mapImg = null; let tokens = []; const worldBounds = [[180, -180],[-180, 180]]; function initializeMap(mapImgUrl) { if (!map) { map = L.map('map', { minZoom: 0, maxZoom: 4, crs: L.CRS.Simple }); map.on("zoomend", ()=>{resizeMarkers();scaleSpritePreview();}); } if (mapImg) { mapImg.removeFrom(map); } mapImg = L.imageOverlay(mapImgUrl, worldBounds); mapImg.addTo(map); map.setMaxBounds(worldBounds); map.setView([0,0], 2); while (tokens.some(t=>t)) { tokens[0].m.removeFrom(map); tokens.shift(); } } // this works but assumes the map is square (reasonable limitation I think) function resizeMarkers() { tokens.forEach(t=>{ const icon = t.m.options.icon; const scaleFactor = mapImg._image.clientWidth / mapImg._image.naturalWidth; icon.options.iconSize = [scaleFactor * t.sz[0], scaleFactor * t.sz[1]]; t.m.setIcon(icon); }); } function getCascadingPos() { const topLeft = worldBounds[0]; const n = tokens.length; topLeft[1] += (n+1)*5; topLeft[0] -= (n+1)*5; return topLeft; } function addToken(token) { const self = { sz: token.sz, m: L.marker(token.pos, { icon: L.icon({ iconUrl: token.img, iconSize: token.sz, }), title: token.name, draggable: true, autoPan: true })}; tokens.push(self); self.m.addTo(map); } // token for testing in browser console const t = { img: "https://nilfm.cc/favicon.png", sz: [32,32], pos: [0,0], name: "test", }