console.log('Loaded Locations Map'); // DYNAMIC MAP FOR PARTICIPATING LOCATIONS // map container (an element must exist on the page, e.g. add this div to the module) const mapId = 'map-galleria-percorso'; const mapLinkId = mapId + '-link'; const defaultLogo = 'https://cdn.sitetheory.io/nest001/site/1572/461423/Galleria%20Diffusa%20-%20Logo-xs.png'; // Change for Language const appEl = document.getElementById('app'); const appClasses = appEl ? [...appEl.classList] : []; const lang = appClasses.find(c => c.startsWith('lang-'))?.split('lang-')[1] || 'it'; const text = { confirm: lang === 'en' ? 'confirm' : 'conferma', artist: lang === 'en' ? 'artist' : 'artista', website: 'website', instagram: 'instagram' }; const defaultMapConfig = { locationsUrl: null, startingLocation: null, disableArtistName: false, zoomMin: 13, // city wide zoomMax: 16 // for single marker }; const customMapConfig = window.mapConfig || {}; const mapConfig = Object.assign(defaultMapConfig, customMapConfig); // Fetch locations JSON function fetchLocations(url) { if (!url) { console.error('fetchLocations: no URL provided'); return Promise.reject(new Error('No locations URL')); } return fetch(url) .then(response => { if (!response.ok) { throw new Error('Failed to load locations JSON: ' + response.status); } return response.json(); // assumes the .txt is valid JSON }); } // This executes on callback AFTER Google Maps loads let map, mapCenter, mapZoom; function boundsAreTiny(b) { const ne = b.getNorthEast(); const sw = b.getSouthWest(); const latSpan = Math.abs(ne.lat() - sw.lat()); const lngSpan = Math.abs(ne.lng() - sw.lng()); return latSpan < 0.002 && lngSpan < 0.002; // ~ a couple hundred meters } function buildMap(el, locations) { map = new google.maps.Map(el, { // MapId from console.cloud.google.com/google/maps-apis mapId: '96d47af0d151e2742dd5dfc5', mapTypeId: 'roadmap', disableDefaultUI: false, zoomControl: true, mapTypeControl: true, streetViewControl: false, fullscreenControl: true, clickableIcons: false }); const bounds = new google.maps.LatLngBounds(); const info = new google.maps.InfoWindow(); const stops = []; // requires &libraries=marker in the loader const pin = new google.maps.marker.PinElement({ background: '#f7931e', // fill borderColor: '#8d4e00', // stroke // glyph: '+', // text/icon in the pin glyphColor: '#8d4e00', scale: 1 // size multiplier }); /* const img = document.createElement('img'); img.src = 'https://cdn.sitetheory.io/.../marker.svg'; // SVG or 2x PNG img.width = 36; // visual size img.height = 36; // bottom-center anchor img.style.transform = 'translate(-50%, -100%)'; img.style.position = 'absolute'; // optional styling img.style.filter = 'drop-shadow(0 2px 6px rgba(0,0,0,.35))'; */ locations.forEach(loc => { const marker = new google.maps.marker.AdvancedMarkerElement({ map, position: loc.position, title: loc.title, gmpClickable: true, content: pin.element.cloneNode(true) }); const locationImage = loc.image || loc.logo || defaultLogo; let content = `
${loc.title}
${loc.addressShort}
${loc.hours} (${text.confirm})
${loc.website ? `${text.website}: ${loc.websiteShort}
` : ''} ${loc.instagram ? `${text.instagram}: @${loc.instagramShort}
` : ''} ${!mapConfig.disableArtistName && loc.artist ? `${text.artist}: ${loc.artist.name}
` : ''}