|
|
| Line 1: |
Line 1: |
| /* Any JavaScript here will be loaded for all users on every page load. */ | | /* Any JavaScript here will be loaded for all users on every page load. */ |
| (function(){
| |
| // --- Leaflet CSS/JS ---
| |
| var LCSS='https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
| |
| var LJS ='https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
| |
| if (!document.querySelector('link[href="'+LCSS+'"]')) {
| |
| var l=document.createElement('link'); l.rel='stylesheet'; l.href=LCSS; document.head.appendChild(l);
| |
| }
| |
| function loadScript(src, cb){ var s=document.createElement('script'); s.src=src; s.onload=cb; document.head.appendChild(s); }
| |
| function fileUrl(title){ return new URL(mw.util.getUrl('Special:FilePath/'+title), location.origin).href; }
| |
|
| |
| // --- CSS for emoji markers ---
| |
| (function(){
| |
| var css = `
| |
| .tv-icon{display:flex;align-items:center;justify-content:center;
| |
| width:30px;height:30px;border-radius:50%;box-shadow:0 0 0 2px #fff, 0 2px 6px rgba(0,0,0,.25);
| |
| font-size:18px;line-height:1;}
| |
| .tv-icon-boss{ background:#c0392b; } /* red */
| |
| .tv-icon-pebble{ background:#7f8c8d; } /* gray */
| |
| .tv-icon-logs{ background:#8e5a2b; } /* brown */
| |
| .tv-icon span{ transform:translateY(1px); }
| |
| `;
| |
| var st=document.createElement('style'); st.textContent=css; document.head.appendChild(st);
| |
| })();
| |
|
| |
| // === CONFIG ===
| |
| var MAP_IMAGE_FILE = 'TreeverseMap.png'; // exact filename of your uploaded map
| |
| // ==============
| |
|
| |
| // Make a divIcon with emoji
| |
| function makeEmojiIcon(kind){
| |
| var cls = 'tv-icon ';
| |
| var emoji = '❓';
| |
| if (kind==='boss'){ cls+='tv-icon-boss'; emoji='👹'; }
| |
| else if (kind==='pebble'){ cls+='tv-icon-pebble'; emoji='🪨'; }
| |
| else if (kind==='logs'){ cls+='tv-icon-logs'; emoji='🪓'; }
| |
| return L.divIcon({
| |
| className: cls,
| |
| html: '<span>'+emoji+'</span>',
| |
| iconSize: [30,30],
| |
| iconAnchor: [15,30],
| |
| popupAnchor: [0,-24]
| |
| });
| |
| }
| |
|
| |
| // Control for adding markers
| |
| function makeControl(map, layers){
| |
| var c=L.control({position:'topright'});
| |
| c.onAdd=function(){
| |
| var d=L.DomUtil.create('div','leaflet-bar');
| |
| d.style.padding='8px'; d.style.background='#fff'; d.style.minWidth='220px'; d.style.font='14px/1.2 sans-serif';
| |
| d.innerHTML=''
| |
| +'<div style="font-weight:600;margin-bottom:6px">Add marker</div>'
| |
| +'<label style="display:block;margin:4px 0 2px">Type</label>'
| |
| +'<select id="tm-type" style="width:100%">'
| |
| +'<option value="boss">Boss 👹</option>'
| |
| +'<option value="pebble">Pebble 🪨</option>'
| |
| +'<option value="logs">Logs 🪓</option>'
| |
| +'</select>'
| |
| +'<label style="display:block;margin:6px 0 2px">Title</label>'
| |
| +'<input id="tm-title" placeholder="Name…" style="width:100%;box-sizing:border-box">'
| |
| +'<label style="display:block;margin:6px 0 2px">Coords (y, x)</label>'
| |
| +'<input id="tm-y" placeholder="y" style="width:48%">'
| |
| +'<input id="tm-x" placeholder="x" style="width:48%;float:right">'
| |
| +'<div style="clear:both;margin-top:8px"></div>'
| |
| +'<button id="tm-add" class="mw-ui-button" style="width:100%">Add</button>';
| |
| L.DomEvent.disableClickPropagation(d);
| |
|
| |
| var addMarker=function(){};
| |
| d.querySelector('#tm-add').onclick=function(){
| |
| var t=d.querySelector('#tm-type').value,
| |
| title=(d.querySelector('#tm-title').value||'').trim(),
| |
| y=parseFloat(d.querySelector('#tm-y').value),
| |
| x=parseFloat(d.querySelector('#tm-x').value);
| |
| if(isNaN(y)||isNaN(x)){alert('Enter numbers for y and x');return;}
| |
| addMarker(t,[y,x],title||t);
| |
| };
| |
| c.setAddMarker=function(fn){ addMarker=fn; };
| |
| c.setInputs=function(latlng){
| |
| d.querySelector('#tm-y').value=Math.round(latlng.lat);
| |
| d.querySelector('#tm-x').value=Math.round(latlng.lng);
| |
| };
| |
| return d;
| |
| };
| |
| c.addTo(map); return c;
| |
| }
| |
|
| |
| function init(){
| |
| var img=new Image(), mapImgUrl=fileUrl(MAP_IMAGE_FILE);
| |
| img.onload=function(){
| |
| var w=img.naturalWidth, h=img.naturalHeight;
| |
| if(!w||!h){ alert('Could not read size for '+MAP_IMAGE_FILE); return; }
| |
| var el=document.getElementById('treeverse-map'); if(!el) return;
| |
| var map=L.map(el,{crs:L.CRS.Simple,minZoom:-2,maxZoom:5});
| |
| var bounds=[[0,0],[h,w]];
| |
| L.imageOverlay(mapImgUrl,bounds).addTo(map);
| |
| map.fitBounds(bounds);
| |
|
| |
| var layers={ boss:L.layerGroup().addTo(map),
| |
| pebble:L.layerGroup().addTo(map),
| |
| logs:L.layerGroup().addTo(map) };
| |
| var icons={ boss:makeEmojiIcon('boss'),
| |
| pebble:makeEmojiIcon('pebble'),
| |
| logs:makeEmojiIcon('logs') };
| |
|
| |
| function addMarker(type,latlng,title){
| |
| var m=L.marker(latlng,{icon:icons[type],title:title||type}).addTo(layers[type]);
| |
| m.bindPopup('<b>'+ (title||type) +'</b><br>(y:'+Math.round(latlng[0])+', x:'+Math.round(latlng[1])+')');
| |
| return m;
| |
| }
| |
|
| |
| var control=makeControl(map,layers);
| |
| control.setAddMarker(addMarker);
| |
| map.on('click',e=>control.setInputs(e.latlng));
| |
|
| |
| L.control.layers(null,{
| |
| 'Bosses 👹':layers.boss,
| |
| 'Pebbles 🪨':layers.pebble,
| |
| 'Logs 🪓':layers.logs
| |
| },{collapsed:false}).addTo(map);
| |
|
| |
| // Example starter markers
| |
| addMarker('town',[Math.round(h*0.55),Math.round(w*0.45)],'Spawn'); // optional
| |
| addMarker('pebble',[Math.round(h*0.40),Math.round(w*0.70)],'Pebble Patch');
| |
| addMarker('boss',[Math.round(h*0.25),Math.round(w*0.30)],'Ancient Demon');
| |
| addMarker('logs',[Math.round(h*0.60),Math.round(w*0.60)],'Logging Camp');
| |
| };
| |
| img.onerror=function(){ alert('Could not load map image "'+MAP_IMAGE_FILE+'". Check Special:ListFiles.'); };
| |
| img.src=mapImgUrl+'?v='+Date.now();
| |
| }
| |
|
| |
| loadScript(LJS, init);
| |
| })();
| |