The plan is where the operator changes the seating. A drag starts only past a movement threshold, so a click is never a drag (§ 8.4), and Escape cancels it; a person dropped on a chair is moved or swapped through the places commands, a table is moved, and a handle resizes it after the capacity check. A refusal appears on the place where the gesture ended. A new gesture waits for the previous write, so a second drag never starts from a stale plan, and nothing reads layout while a drag runs. Checked: 2499 node and 436 browser tests. --- FR --- [ADD] interface : gestes du plan — glisser une personne, une table Le plan est l'endroit où l'opérateur change le placement. Un glissement ne commence qu'au-delà d'un seuil de mouvement — un clic n'en est jamais un (§ 8.4) — et Échap l'annule ; une personne déposée sur une chaise est déplacée ou échangée par les commandes des places, une table se déplace, et une poignée la redimensionne après le contrôle de capacité. Un refus se pose sur la place où le geste a fini. Un geste attend l'écriture du précédent, si bien qu'un second glissement ne part jamais d'un plan périmé, et rien ne lit la mise en page pendant un glissement. Vérifié : 2499 node et 436 navigateur. Assisted-by: Claude Opus 5.5
55 lines
1.7 KiB
Svelte
55 lines
1.7 KiB
Svelte
<!-- © 2026 TechnoLibre (http://www.technolibre.ca)
|
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -->
|
|
|
|
<svelte:options namespace="svg" />
|
|
|
|
<script>
|
|
// Le fantôme d'une personne glissée (§ 5.8, § 7.1) : un <g data-fantome>
|
|
// permanent, enfant du <svg data-plan> hors du groupe de la vue, dont
|
|
// l'unité est le pixel CSS — il garde sa taille à tout zoom. Plan.svelte
|
|
// écrit son attribut transform à chaque image, directement, et le montre
|
|
// par la propriété fantome : le nom de la personne, dans son propre nœud,
|
|
// puis le libellé de ce que le geste modifie — la clé que cleFantome
|
|
// (gestes.js) tire de la cible de l'état des places. Caché, il ne porte
|
|
// rien ; montré ou non, il ne reçoit pas le pointeur.
|
|
//
|
|
// fantome : {nom, cle} | null ; element : le <g>, lié pour Plan.svelte.
|
|
import { getContext } from 'svelte';
|
|
|
|
let { fantome = null, element = $bindable(null) } = $props();
|
|
|
|
const t = getContext('t');
|
|
</script>
|
|
|
|
<g class="fantome" class:cache={fantome === null} data-fantome bind:this={element}>
|
|
{#if fantome !== null}
|
|
<circle class="disque" data-marque="fantome" r="10" />
|
|
<text class="texte" x="16" y="-6"
|
|
><tspan data-partie="nom">{fantome.nom}</tspan><tspan x="16" dy="1.25em" data-partie="etat">{t(fantome.cle)}</tspan></text
|
|
>
|
|
{/if}
|
|
</g>
|
|
|
|
<style>
|
|
.fantome {
|
|
pointer-events: none;
|
|
}
|
|
|
|
.fantome.cache {
|
|
display: none;
|
|
}
|
|
|
|
.disque {
|
|
fill: none;
|
|
stroke: var(--couleur-fantome);
|
|
stroke-width: 4;
|
|
}
|
|
|
|
.texte {
|
|
fill: var(--couleur-liste-texte);
|
|
font-family: var(--police-interface);
|
|
font-size: var(--taille-texte);
|
|
font-weight: 700;
|
|
white-space: pre;
|
|
}
|
|
</style>
|