const franceCoordinates = { // https://boundingbox.klokantech.com/ metropole: { latTop: 51.1, // Nord-Ouest (coin supérieur gauche) lonLeft: -5.15, latBottom: 41.3, // Sud-Est (coin inférieur droit) lonRight: 9.65, }, guadeloupe: { latTop: 16.5, lonLeft: -62, latBottom: 15.8, lonRight: -60.8, }, martinique: { latTop: 14.9, lonLeft: -61.3, latBottom: 14.3, lonRight: -60.7, }, guyanne: { latTop: 6, lonLeft: -54.8, latBottom: 1.8, lonRight: -51.2, }, reunion: { latTop: -20.8, lonLeft: 55.1, latBottom: -21.4, lonRight: 55.9, }, saintPierreEtMiquelon: { latTop: 47.15, lonLeft: -56.41, latBottom: 46.74, lonRight: -56.13, }, mayotte: { latTop: -12.63, lonLeft: 45.01, latBottom: -13.02, lonRight: 45.3, }, saintBarthelemy: { latTop: 17.97, lonLeft: -62.94, latBottom: 17.87, lonRight: -62.78, }, saintMartin: { latTop: 18.12, lonLeft: -63.15, latBottom: 18, lonRight: -62.97, }, futuna: { latTop: -14.23, lonLeft: -178.18, latBottom: -14.36, lonRight: -177.99, }, wallis: { latTop: -13.21, lonLeft: -176.25, latBottom: -13.39, lonRight: -176.15, }, polynesieFrancaise: { latTop: -17.47, lonLeft: -149.91, latBottom: -17.89, lonRight: -149.12, }, nouvelleCaledonie: { latTop: -19.3, lonLeft: 163.3, latBottom: -22.9, lonRight: 168.4, }, }; const localisationMapPlacements = { // en pourcentage de la largeur et hauteur du fond de carte metropole: { top: 0, left: 12.9, bottom: 63.48, right: 87.14, }, guadeloupe: { top: 87.8, left: 33.01, bottom: 98.77, right: 46.25, }, martinique: { top: 88.3, left: 53.26, bottom: 98.24, right: 61.99, }, guyanne: { top: 87.5, left: 69.09, bottom: 99.21, right: 79.07, }, reunion: { top: 75, left: 89.6, bottom: 82.04, right: 97.88, }, saintPierreEtMiquelon: { top: 86, left: 2, bottom: 99.6, right: 9, }, mayotte: { top: 88, left: 17.08, bottom: 98.68, right: 26.19, }, saintBarthelemy: { top: 74.5, left: 44.81, bottom: 82.74, right: 57.58, }, saintMartin: { top: 74.2, left: 23.12, bottom: 82.92, right: 36.08, }, futuna: { top: 74.2, left: 0, bottom: 79, right: 7.5, }, wallis: { top: 75.8, left: 9.1, bottom: 82, right: 13, }, polynesieFrancaise: { top: 89.5, left: 85.12, bottom: 97.02, right: 100, }, nouvelleCaledonie: { top: 73.73, left: 66.21, bottom: 83.80, right: 81.09, }, }; const projectsIcons = document.querySelectorAll('#projects_icons > svg'); for (let icon of projectsIcons) { icon.addEventListener('mouseenter', function() { displayPopup(icon); }); icon.addEventListener('mouseleave', function() { hidePopup(); }); } function placeProjectsIcons(projectsIcons, container) { const containerWidth = container.getBoundingClientRect().width; const containerHeight = container.getBoundingClientRect().height; projectsIcons.forEach(icon => { const iconWidth = icon.getBoundingClientRect().width; let lat = parseFloat(icon.dataset.geofieldlat); let lon = parseFloat(icon.dataset.geofieldlon); if (lat > 180) lat = lat - 360; if (lon > 180) lon = lon - 360; const territory = findTerritory(lat, lon); // console.log(icon.dataset.title, territory); if (territory && localisationMapPlacements[territory]) { const territoryBounds = localisationMapPlacements[territory]; const territoryCoords = franceCoordinates[territory]; const xPercentage = ((lon - territoryCoords.lonLeft) / (territoryCoords.lonRight - territoryCoords.lonLeft)) * 100; const yPercentage = ((territoryCoords.latTop - lat) / (territoryCoords.latTop - territoryCoords.latBottom)) * 100; const finalX = containerWidth * (territoryBounds.left / 100 + (xPercentage / 100) * (territoryBounds.right - territoryBounds.left) / 100) - iconWidth / 2; const finalY = containerHeight * (territoryBounds.top / 100 + (yPercentage / 100) * (territoryBounds.bottom - territoryBounds.top) / 100) - iconWidth / 2; // icon.setAttribute('transform', `translate(${finalX}, ${finalY})`); // does not seems to be working on mobile icon.style.left = `${finalX}px`; icon.style.top = `${finalY}px`; } else { console.warn(`Territory not found for lat: ${lat}, lon: ${lon}`); } }); } function findTerritory(lat, lon) { for (const [territory, coords] of Object.entries(franceCoordinates)) { if (lat > 180) lat = lat - 360; if (lon > 180) lon = lon - 360; if ( lat <= Math.max(coords.latTop, coords.latBottom) && lat >= Math.min(coords.latTop, coords.latBottom) && lon >= Math.min(coords.lonLeft, coords.lonRight) && lon <= Math.max(coords.lonLeft, coords.lonRight) ) { return territory; } } return "Unknown territory"; } let isPopupVisible = false; function displayPopup(icon) { const container = document.querySelector('#sites-map-container'); const x = icon.getBoundingClientRect().left - container.getBoundingClientRect().left; const y = icon.getBoundingClientRect().top - container.getBoundingClientRect().top; const popup = document.querySelector('#sites-map-container #popup'); popup.querySelector('h3').innerText = icon.dataset.title; popup.querySelector('p').innerText = icon.dataset.place; popup.style.top = 0; popup.style.left = 0; popup.style.display = 'block'; popup.style.left = `${x - popup.getBoundingClientRect().width / 2 + icon.getBoundingClientRect().width / 2}px`; popup.style.top = `${y - popup.getBoundingClientRect().height - icon.getBoundingClientRect().height}px`; setTimeout(() => { popup.style.opacity = 1; }, 10); isPopupVisible = true; } function hidePopup(){ const popup = document.querySelector('#sites-map-container #popup'); popup.style.opacity = 0; setTimeout(() => { if (!isPopupVisible) popup.style.display = 'none'; isPopupVisible = false; }, 300); } // debugMapPlacement(); document.addEventListener('DOMContentLoaded', () => { let containerImg = document.querySelector('#map_base'); containerImg.addEventListener('load', () => { placeProjectsIcons(projectsIcons, containerImg); window.addEventListener('resize', () => { placeProjectsIcons(projectsIcons, containerImg); }); }) if (containerImg.complete) { placeProjectsIcons(projectsIcons, containerImg); } }); function debugMapPlacement() { const container = document.querySelector('#sites-map-container'); for (let territory of Object.keys(localisationMapPlacements)) { const debugDiv = document.createElement('div'); debugDiv.style.position = 'absolute'; debugDiv.innerText = territory; debugDiv.style.fontSize = '10px'; debugDiv.style.top = localisationMapPlacements[territory].top + '%'; debugDiv.style.left = localisationMapPlacements[territory].left + '%'; debugDiv.style.width = (localisationMapPlacements[territory].right - localisationMapPlacements[territory].left) + '%'; debugDiv.style.height = (localisationMapPlacements[territory].bottom - localisationMapPlacements[territory].top) + '%'; debugDiv.style.backgroundColor = 'rgba(255, 0, 0, 0.5)'; debugDiv.style.pointerEvents = 'none'; container.appendChild(debugDiv); } }