MediaWiki:Common.js: Difference between revisions

From Rise of Agon Wiki
Admin (talk | contribs)
Add Leaflet map integration
Admin (talk | contribs)
Switch map to tile pyramid
Line 1: Line 1:
// Custom Agon World Map with Leaflet
// Custom Agon World Map with Leaflet (tiled)
(function() {
(function() {
     // Only run on map pages
     // Only run on map pages
     if (!document.getElementById('agon-map-container')) return;
     if (!document.getElementById('agon-map-container')) return;
   
 
     // Load Leaflet CSS
     // Load Leaflet CSS
     var link = document.createElement('link');
     var link = document.createElement('link');
Line 9: Line 9:
     link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
     link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
     document.head.appendChild(link);
     document.head.appendChild(link);
   
 
     // Load Leaflet JS
     // Load Leaflet JS
     var script = document.createElement('script');
     var script = document.createElement('script');
Line 22: Line 22:
     var mapContainer = document.getElementById('agon-map-container');
     var mapContainer = document.getElementById('agon-map-container');
     if (!mapContainer) return;
     if (!mapContainer) return;
   
 
     // Image dimensions
     // Image dimensions
     var imageWidth = 16384;
     var imageWidth = 16384;
     var imageHeight = 16384;
     var imageHeight = 16384;
      
     var tileSize = 512;
    var maxZoom = 5; // derived from 16384 / 512 = 32 => log2(32) = 5
 
    // Bounds for the simple CRS (y, x order)
    var bounds = [[0, 0], [imageHeight, imageWidth]];
 
     // Create map with custom CRS for image coordinates
     // Create map with custom CRS for image coordinates
     var map = L.map('agon-map-container', {
     var map = L.map('agon-map-container', {
         crs: L.CRS.Simple,
         crs: L.CRS.Simple,
         minZoom: -3,
         minZoom: 0,
         maxZoom: 2,
         maxZoom: maxZoom,
         center: [imageHeight/2, imageWidth/2],
         center: [imageHeight / 2, imageWidth / 2],
         zoom: -2
         zoom: 1
     });
     });
   
 
     // Add the Agon map image as overlay
     // Tile layer using generated pyramid under /resources/assets/tiles/AgonBigMap/{z}/{x}/{y}.jpg
     var bounds = [[0, 0], [imageHeight, imageWidth]];
     var tileUrl = mw.config.get('wgScriptPath') + '/resources/assets/tiles/AgonBigMap/{z}/{x}/{y}.jpg';
    L.imageOverlay(mw.config.get('wgScriptPath') + '/resources/assets/AgonBigMap.png', bounds).addTo(map);
    L.tileLayer(tileUrl, {
   
        tileSize: tileSize,
     // Fit map to bounds
        minZoom: 0,
        maxZoom: maxZoom,
        maxNativeZoom: maxZoom,
        bounds: bounds,
        noWrap: true
    }).addTo(map);
 
     // Fit map to bounds and keep panning constrained
     map.fitBounds(bounds);
     map.fitBounds(bounds);
      
     map.setMaxBounds(bounds);
 
     // Add scale
     // Add scale
     L.control.scale().addTo(map);
     L.control.scale().addTo(map);
   
 
     // Click to get coordinates
     // Click to get coordinates
     map.on('click', function(e) {
     map.on('click', function(e) {
         var coord = e.latlng;
         var coord = e.latlng;
         console.log('Clicked coordinates:', coord.lat.toFixed(2) + ', ' + coord.lng.toFixed(2));
         var text = 'Coordinates: ' + coord.lat.toFixed(2) + ', ' + coord.lng.toFixed(2);
        console.log(text);
         L.popup()
         L.popup()
             .setLatLng(e.latlng)
             .setLatLng(e.latlng)
             .setContent('Coordinates: ' + coord.lat.toFixed(2) + ', ' + coord.lng.toFixed(2))
             .setContent(text)
             .openOn(map);
             .openOn(map);
     });
     });
   
 
     // Load markers from page data
     // Load markers from page data
     if (window.agonMapMarkers) {
     if (window.agonMapMarkers) {
Line 66: Line 80:
                 popupAnchor: [1, -34]
                 popupAnchor: [1, -34]
             });
             });
           
 
             L.marker([coords[0], coords[1]], {icon: icon})
             L.marker([coords[0], coords[1]], { icon: icon })
                 .addTo(map)
                 .addTo(map)
                 .bindPopup('<b>' + marker.name + '</b><br>' + marker.description);
                 .bindPopup('<b>' + marker.name + '</b><br>' + marker.description);

Revision as of 09:01, 25 January 2026

// Custom Agon World Map with Leaflet (tiled)
(function() {
    // Only run on map pages
    if (!document.getElementById('agon-map-container')) return;

    // Load Leaflet CSS
    var link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
    document.head.appendChild(link);

    // Load Leaflet JS
    var script = document.createElement('script');
    script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
    script.onload = function() {
        initAgonMap();
    };
    document.head.appendChild(script);
})();

function initAgonMap() {
    var mapContainer = document.getElementById('agon-map-container');
    if (!mapContainer) return;

    // Image dimensions
    var imageWidth = 16384;
    var imageHeight = 16384;
    var tileSize = 512;
    var maxZoom = 5; // derived from 16384 / 512 = 32 => log2(32) = 5

    // Bounds for the simple CRS (y, x order)
    var bounds = [[0, 0], [imageHeight, imageWidth]];

    // Create map with custom CRS for image coordinates
    var map = L.map('agon-map-container', {
        crs: L.CRS.Simple,
        minZoom: 0,
        maxZoom: maxZoom,
        center: [imageHeight / 2, imageWidth / 2],
        zoom: 1
    });

    // Tile layer using generated pyramid under /resources/assets/tiles/AgonBigMap/{z}/{x}/{y}.jpg
    var tileUrl = mw.config.get('wgScriptPath') + '/resources/assets/tiles/AgonBigMap/{z}/{x}/{y}.jpg';
    L.tileLayer(tileUrl, {
        tileSize: tileSize,
        minZoom: 0,
        maxZoom: maxZoom,
        maxNativeZoom: maxZoom,
        bounds: bounds,
        noWrap: true
    }).addTo(map);

    // Fit map to bounds and keep panning constrained
    map.fitBounds(bounds);
    map.setMaxBounds(bounds);

    // Add scale
    L.control.scale().addTo(map);

    // Click to get coordinates
    map.on('click', function(e) {
        var coord = e.latlng;
        var text = 'Coordinates: ' + coord.lat.toFixed(2) + ', ' + coord.lng.toFixed(2);
        console.log(text);
        L.popup()
            .setLatLng(e.latlng)
            .setContent(text)
            .openOn(map);
    });

    // Load markers from page data
    if (window.agonMapMarkers) {
        window.agonMapMarkers.forEach(function(marker) {
            var coords = marker.coordinates.split(',').map(parseFloat);
            var icon = L.icon({
                iconUrl: marker.icon || mw.config.get('wgScriptPath') + '/resources/assets/marker-icon.png',
                iconSize: [25, 41],
                iconAnchor: [12, 41],
                popupAnchor: [1, -34]
            });

            L.marker([coords[0], coords[1]], { icon: icon })
                .addTo(map)
                .bindPopup('<b>' + marker.name + '</b><br>' + marker.description);
        });
    }
}