Borner la barre de comparaison hors du panneau et des outils, poignée au-dessus du volet

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Antoine Jacquin
2026-09-27 19:54:00 +02:00
parent 857a9e55d6
commit 0df93c2f00
3 changed files with 45 additions and 8 deletions

View File

@ -60,7 +60,9 @@ html, body { height: 100%; overflow: hidden; background: var(--bg); color: var(-
/* Mode Comparer : barre glissante qui sépare les deux couches. */
#compareBar { position: fixed; top: 0; bottom: 0; width: 4px; margin-left: -2px; z-index: var(--z-map-ui);
background: var(--surface); box-shadow: var(--shadow-sm); cursor: ew-resize; touch-action: none; }
#compareBar span { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
/* Poignée au milieu de la carte visible, au-dessus du volet (téléphone) : à
mi-hauteur de l'écran elle tombait sous l'échelle Leaflet posée sur le volet. */
#compareBar span { position: absolute; top: calc((100% - var(--sheet-h)) / 2); left: 50%; transform: translate(-50%, -50%);
width: 36px; height: 36px; border-radius: var(--r-full); display: flex; align-items: center;
justify-content: center; background: var(--surface); color: var(--text); border: 1px solid var(--border);
box-shadow: var(--shadow-sm); font-size: var(--fs-lg); }

View File

@ -425,15 +425,36 @@ function applyLayers() {
updateRose();
}
// Plage de la séparation, en px du conteneur de la carte : la poignée reste
// dans la partie visible de la carte, jamais sous le panneau (ordinateur :
// panneau ouvert ou bande d'icônes, toute la hauteur) ni sous la colonne
// d'outils. COMPARE_MARGIN = demi-largeur de la poignée + marge.
const COMPARE_MARGIN = 24;
function compareBounds() {
const r = map.getContainer().getBoundingClientRect();
let min = COMPARE_MARGIN, max = r.width - COMPARE_MARGIN;
if (!isPhone()) {
min = Math.max(min, el('panel').getBoundingClientRect().right - r.left + COMPARE_MARGIN);
max = Math.min(max, el('tools').getBoundingClientRect().left - r.left - COMPARE_MARGIN);
}
// Fenêtre trop étroite : la séparation reste au milieu de la plage.
if (min > max) min = max = (min + max) / 2;
return { left: r.left, min, max };
}
// Découpe des couches de part et d'autre de la barre, en coordonnées de
// calque (les conteneurs de tuiles se déplacent avec la carte) : recalculée
// à chaque déplacement. Même couche des deux côtés : aucune découpe.
// STATE.compare.pos garde la valeur demandée (lien, glisser) ; la séparation
// affichée, barre et découpe ensemble, est bornée à compareBounds().
function applyCompareClip() {
if (!STATE) return;
const on = effectiveMode() === 'compare';
el('compareBar').hidden = !on;
const size = map.getSize();
const x = size.x * (on ? STATE.compare.pos : 50) / 100;
let x = size.x * (on ? STATE.compare.pos : 50) / 100;
const bounds = on ? compareBounds() : null;
if (bounds) x = Math.min(bounds.max, Math.max(bounds.min, x));
const nw = map.containerPointToLayerPoint([0, 0]);
const se = map.containerPointToLayerPoint(size);
const cx = map.containerPointToLayerPoint([x, 0]).x;
@ -448,13 +469,12 @@ function applyCompareClip() {
}
c.style.clipPath = clip;
}
if (on) {
const r = map.getContainer().getBoundingClientRect();
el('compareBar').style.left = (r.left + x) + 'px';
}
if (on) el('compareBar').style.left = (bounds.left + x) + 'px';
}
map.on('move', applyCompareClip);
map.on('resize zoomend', applyCompareClip);
// Panneau replié, déplié, volet redimensionné : la plage de la barre change.
document.addEventListener('panel:tab', applyCompareClip);
(function compareDrag() {
const bar = el('compareBar');
@ -462,8 +482,9 @@ map.on('resize zoomend', applyCompareClip);
bar.addEventListener('pointerdown', (e) => { dragging = true; bar.setPointerCapture(e.pointerId); e.preventDefault(); });
bar.addEventListener('pointermove', (e) => {
if (!dragging) return;
const r = map.getContainer().getBoundingClientRect();
STATE.compare.pos = Math.min(95, Math.max(5, 100 * (e.clientX - r.left) / r.width));
const b = compareBounds();
const x = Math.min(b.max, Math.max(b.min, e.clientX - b.left));
STATE.compare.pos = Math.min(95, Math.max(5, 100 * x / map.getSize().x));
applyCompareClip();
});
const end = () => { if (dragging) { dragging = false; saveState(); } };