update frontend
This commit is contained in:
parent
e452f360f9
commit
6b19131f95
|
|
@ -20,15 +20,54 @@ export function clearAllMarkers(markersRef, expandedElRef) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper: hide/show all markers except one element
|
* Util: rectangles overlap?
|
||||||
*/
|
*/
|
||||||
function setOthersVisibility(markersRef, exceptEl, visible) {
|
function rectsOverlap(a, b) {
|
||||||
|
return !(
|
||||||
|
a.right < b.left ||
|
||||||
|
a.left > b.right ||
|
||||||
|
a.bottom < b.top ||
|
||||||
|
a.top > b.bottom
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide only markers that overlap the expanded card.
|
||||||
|
* - expandedEl: the marker root that is expanded
|
||||||
|
*/
|
||||||
|
export function applyOcclusionForExpanded(markersRef, expandedEl) {
|
||||||
|
if (!expandedEl) return;
|
||||||
|
|
||||||
|
const expandedCard = expandedEl.querySelector(".post-card");
|
||||||
|
if (!expandedCard) return;
|
||||||
|
|
||||||
|
const expandedRect = expandedCard.getBoundingClientRect();
|
||||||
|
const list = markersRef.current || [];
|
||||||
|
|
||||||
|
for (const item of list) {
|
||||||
|
const el = item?.el;
|
||||||
|
if (!el || el === expandedEl) continue;
|
||||||
|
|
||||||
|
// Compute marker rect (bubble + pointer)
|
||||||
|
const r = el.getBoundingClientRect();
|
||||||
|
|
||||||
|
const hide = rectsOverlap(expandedRect, r);
|
||||||
|
|
||||||
|
el.style.visibility = hide ? "hidden" : "visible";
|
||||||
|
el.style.pointerEvents = hide ? "none" : "auto";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset all markers visible
|
||||||
|
*/
|
||||||
|
export function clearOcclusion(markersRef) {
|
||||||
const list = markersRef.current || [];
|
const list = markersRef.current || [];
|
||||||
for (const item of list) {
|
for (const item of list) {
|
||||||
const el = item?.el;
|
const el = item?.el;
|
||||||
if (!el || el === exceptEl) continue;
|
if (!el) continue;
|
||||||
el.style.visibility = visible ? "visible" : "hidden";
|
el.style.visibility = "visible";
|
||||||
el.style.pointerEvents = visible ? "auto" : "none";
|
el.style.pointerEvents = "auto";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,8 +78,8 @@ function setOthersVisibility(markersRef, exceptEl, visible) {
|
||||||
*
|
*
|
||||||
* Règles:
|
* Règles:
|
||||||
* - 1 seul post ouvert à la fois
|
* - 1 seul post ouvert à la fois
|
||||||
* - clic sur la map => ferme (géré dans useMapCore)
|
* - clic sur la map => ferme (useMapCore)
|
||||||
* - quand un post est ouvert => on cache les autres markers pour éviter les overlaps
|
* - quand un post est ouvert => on cache SEULEMENT les markers qui le recouvrent
|
||||||
*/
|
*/
|
||||||
export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
|
|
@ -96,8 +135,8 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
||||||
</div>
|
</div>
|
||||||
<div class="post-pin-pointer-small"></div>
|
<div class="post-pin-pointer-small"></div>
|
||||||
`;
|
`;
|
||||||
// remettre les autres markers visibles
|
// bring back hidden markers
|
||||||
setOthersVisibility(markersRef, root, true);
|
clearOcclusion(markersRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderExpanded() {
|
function renderExpanded() {
|
||||||
|
|
@ -149,14 +188,16 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
||||||
<div class="post-card-pointer"></div>
|
<div class="post-card-pointer"></div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// cacher les autres markers pendant que celui-ci est ouvert
|
// Wait a frame so DOM has final size, then hide only overlapping markers
|
||||||
setOthersVisibility(markersRef, root, false);
|
requestAnimationFrame(() => {
|
||||||
|
applyOcclusionForExpanded(markersRef, root);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// état initial : compact
|
// état initial : compact
|
||||||
renderCompact();
|
renderCompact();
|
||||||
|
|
||||||
// IMPORTANT: garder une ref stable pour useMapCore (clic sur map => ferme)
|
// utilisé par useMapCore pour fermer via clic map
|
||||||
root.__renderCompact = renderCompact;
|
root.__renderCompact = renderCompact;
|
||||||
|
|
||||||
const marker = new maplibregl.Marker({
|
const marker = new maplibregl.Marker({
|
||||||
|
|
@ -179,7 +220,7 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
||||||
expandedElRef.current = null;
|
expandedElRef.current = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle pour ce post
|
// Toggle
|
||||||
const isExpanded = root.classList.contains("post-pin--expanded");
|
const isExpanded = root.classList.contains("post-pin--expanded");
|
||||||
if (isExpanded) {
|
if (isExpanded) {
|
||||||
renderCompact();
|
renderCompact();
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from "react";
|
||||||
import maplibregl from "maplibre-gl";
|
import maplibregl from "maplibre-gl";
|
||||||
import { LAST_VIEW_KEY } from "./mapConfig";
|
import { LAST_VIEW_KEY } from "./mapConfig";
|
||||||
import { getViewFromMap } from "./mapGeo";
|
import { getViewFromMap } from "./mapGeo";
|
||||||
import { clearAllMarkers } from "./markerManager";
|
import { clearAllMarkers, applyOcclusionForExpanded } from "./markerManager";
|
||||||
|
|
||||||
// renvoie le style MapLibre en fonction du thème
|
// renvoie le style MapLibre en fonction du thème
|
||||||
function getBaseStyle(theme) {
|
function getBaseStyle(theme) {
|
||||||
|
|
@ -98,6 +98,14 @@ export function useMapCore(theme) {
|
||||||
map.addControl(new maplibregl.NavigationControl(), "top-right");
|
map.addControl(new maplibregl.NavigationControl(), "top-right");
|
||||||
mapRef.current = map;
|
mapRef.current = map;
|
||||||
|
|
||||||
|
// If a post is expanded, re-apply occlusion on zoom/move (only hides overlapping ones)
|
||||||
|
const reOcclude = () => {
|
||||||
|
const el = expandedElRef.current;
|
||||||
|
if (el) applyOcclusionForExpanded(markersRef, el);
|
||||||
|
};
|
||||||
|
map.on("move", reOcclude);
|
||||||
|
map.on("zoom", reOcclude);
|
||||||
|
|
||||||
// Close expanded post when clicking on the map (outside markers)
|
// Close expanded post when clicking on the map (outside markers)
|
||||||
map.on("click", () => {
|
map.on("click", () => {
|
||||||
const el = expandedElRef.current;
|
const el = expandedElRef.current;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue