@micheeeeel/yinyangapp 2.2.2 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/bundle.js +1 -1
- package/dist/types/api.d.ts +7 -0
- package/dist/types/components/controller/YinYangController.d.ts +167 -5
- package/dist/types/components/controller/action-stack/ActionStackController.d.ts +15 -0
- package/dist/types/components/controller/actions/ChildActionMenuController.d.ts +40 -0
- package/dist/types/components/controller/children/ChildInteractionController.d.ts +9 -0
- package/dist/types/components/controller/force-field/ForceFieldDetailsPanel.d.ts +59 -8
- package/dist/types/components/controller/force-field/ForceFieldLifecycleController.d.ts +17 -0
- package/dist/types/components/controller/force-field/ForceFieldRenderer.d.ts +25 -0
- package/dist/types/components/controller/force-field/types.d.ts +16 -0
- package/dist/types/components/controller/odd/OddHighlightEffects.d.ts +78 -0
- package/dist/types/components/controller/odd/OddViewManager.d.ts +92 -1
- package/dist/types/components/controller/odd/childHighlightStyles.d.ts +79 -0
- package/dist/types/components/controller/search/SearchPanelSynchronizer.d.ts +9 -0
- package/dist/types/components/controller/state/YinYangControllerState.d.ts +23 -0
- package/dist/types/components/view/SpikeDrawer.d.ts +28 -0
- package/dist/types/components/workspace/workspaceTemplate.d.ts +1 -1
- package/dist/types/config/animationConfig.d.ts +7 -0
- package/dist/types/config/propagationCometConfig.d.ts +41 -0
- package/package.json +1 -1
package/dist/types/api.d.ts
CHANGED
|
@@ -44,6 +44,13 @@ export declare function mountYinYang(config: YinYangMountConfig): YinYangMountHa
|
|
|
44
44
|
export declare function createYinYangSvg(config: YinYangSvgConfig): SVGSVGElement | null;
|
|
45
45
|
/** Variante en lot : une seule zone hors écran pour tous les rendus. */
|
|
46
46
|
export declare function createYinYangSvgs(configs: YinYangSvgConfig[]): (SVGSVGElement | null)[];
|
|
47
|
+
/** Durée d'un tour de rotation yin/yang du diagramme (ms), telle qu'elle est
|
|
48
|
+
* configurée côté Sphères (`animationConfig.rotationDurationMs`). Un hôte qui
|
|
49
|
+
* rejoue la même cinématique ailleurs — un film de marker cuit avec
|
|
50
|
+
* `yinYangRotationMs`, ou la variable CSS `--yy-yinyang-rotation` — doit LIRE
|
|
51
|
+
* cette valeur plutôt que la recopier : une vitesse changée ici doit se voir
|
|
52
|
+
* partout, sans resynchronisation manuelle. */
|
|
53
|
+
export declare const YINYANG_ROTATION_DURATION_MS: number;
|
|
47
54
|
export { createYinYangFilmSvg, createYinYangFilmSvgAsync } from "./api-film";
|
|
48
55
|
export type { YinYangFilmConfig, YinYangFilmAsyncOptions } from "./api-film";
|
|
49
56
|
export { createRandomCause } from "./api-random";
|
|
@@ -710,11 +710,47 @@ export declare class YinYangController implements IYinYangController {
|
|
|
710
710
|
private _computeCrossComponentCascadeRows;
|
|
711
711
|
private renderForceFieldDetails;
|
|
712
712
|
private flashChildCuttings;
|
|
713
|
-
/**
|
|
714
|
-
*
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
private
|
|
713
|
+
/** Waypoint d'un satellite de la facette courante (par index orbital). Le
|
|
714
|
+
* contrôleur peut être passé quand l'appelant l'a déjà sous la main. */
|
|
715
|
+
private _resolveOrbitWaypoint;
|
|
716
|
+
/** Waypoint sur l'arc de bordure d'une autre facette (cible inter-facettes). */
|
|
717
|
+
private _resolveBorderWaypoint;
|
|
718
|
+
/** `color` avec l'opacité `alpha` (chaîne CSS). */
|
|
719
|
+
private static _withAlpha;
|
|
720
|
+
/**
|
|
721
|
+
* Couleur de la comète : celle de l'action portant l'emphase (aperçu ??
|
|
722
|
+
* focus) quand le réglage le demande et qu'elle est identifiable, sinon la
|
|
723
|
+
* couleur fixe du réglage.
|
|
724
|
+
*/
|
|
725
|
+
private _resolvePropagationColor;
|
|
726
|
+
/** Anneau doux (couleur de la comète) autour d'un satellite atteint :
|
|
727
|
+
* un cercle qui s'élargit en s'éteignant, plus une brève lueur pleine.
|
|
728
|
+
* Intensité réglable (ringOpacity, 0 = rien). */
|
|
729
|
+
private _drawFlashRings;
|
|
730
|
+
/**
|
|
731
|
+
* Joue une passe de propagation sur des waypoints déjà résolus : lueur sur
|
|
732
|
+
* la source, comète parcourant tout le chemin d'un seul mouvement (en
|
|
733
|
+
* pulsant chaque lien de champ de force à son entrée), anneau à chaque
|
|
734
|
+
* arrivée. Partagée par le clic sur une ligne du panneau
|
|
735
|
+
* (flashChildCuttings) et par la boucle de l'action en focus
|
|
736
|
+
* (flashSourcePropagationTree). Retourne la durée totale de la passe en ms
|
|
737
|
+
* (comète éteinte et dernier anneau fondu), pour cadencer la boucle.
|
|
738
|
+
*/
|
|
739
|
+
private _animateResolvedPropagation;
|
|
740
|
+
/**
|
|
741
|
+
* Comète parcourant `waypoints` (polyligne) d'un seul mouvement : vitesse
|
|
742
|
+
* de croisière réglable, départ et arrivée adoucis (easeSinInOut sur tout
|
|
743
|
+
* le trajet), fondu d'apparition/extinction, halo flouté, et queue fondue
|
|
744
|
+
* reconstituée à partir des positions récentes (elle épouse donc les
|
|
745
|
+
* virages aux étapes au lieu de se couper à chaque segment). Tout est
|
|
746
|
+
* déterministe en fonction du temps écoulé : la queue se calcule sans
|
|
747
|
+
* historique, en rééchantillonnant la position à t − Δ.
|
|
748
|
+
* `onWaypointArrival(wp)` à chaque étape atteinte (sauf la source),
|
|
749
|
+
* `onSegmentStart(i)` à l'entrée dans chaque segment. `isCancelled` lu à
|
|
750
|
+
* chaque frame : vrai → la comète disparaît net. Retourne la durée du
|
|
751
|
+
* trajet (ms), fondu de sortie non compris.
|
|
752
|
+
*/
|
|
753
|
+
private _animateComet;
|
|
718
754
|
private getCurrentComponent;
|
|
719
755
|
private getCurrentComponentOrUndefined;
|
|
720
756
|
private getCurrentComponentTitle;
|
|
@@ -769,6 +805,9 @@ export declare class YinYangController implements IYinYangController {
|
|
|
769
805
|
private clearProjectedActionState;
|
|
770
806
|
private applyEmptyGhostProjectionState;
|
|
771
807
|
private updateChildActionMenu;
|
|
808
|
+
/** Sélectionne (ouvre) le satellite `childKey` de la facette courante,
|
|
809
|
+
* comme un clic dessus — sans toggle-close s'il est déjà actif. */
|
|
810
|
+
private selectSatelliteByKey;
|
|
772
811
|
/**
|
|
773
812
|
* Appelé par YinYangDrawer quand le petit cercle "œil" du lobe dominant
|
|
774
813
|
* (yin ou yang, selon Composante.orientation) est cliqué — jamais l'autre
|
|
@@ -969,7 +1008,130 @@ export declare class YinYangController implements IYinYangController {
|
|
|
969
1008
|
* rejoignant leur position de base dans une durée fixe `durationMs`
|
|
970
1009
|
* (troisième mode d'arrêt — voir AnimationsMngr.stopRotationFast). */
|
|
971
1010
|
stopRotationAllFast(durationMs: number): void;
|
|
1011
|
+
/**
|
|
1012
|
+
* Satellites atteints par la propagation de l'action en cours (source
|
|
1013
|
+
* racine comprise), résolus depuis les liens du champ de force via leur
|
|
1014
|
+
* index orbital — la même correspondance index → satellite qu'utilise
|
|
1015
|
+
* ForceFieldRenderer pour tracer les segments. Ils gardent leur apparence
|
|
1016
|
+
* normale quand une mise en valeur éteint le reste de la constellation.
|
|
1017
|
+
*/
|
|
1018
|
+
private getPropagationTargetChildKeys;
|
|
1019
|
+
/**
|
|
1020
|
+
* Rejoue tout ce qui dépend de l'onglet actif (RECHERCHE vs STACK) : la
|
|
1021
|
+
* mise en valeur des ODD et du satellite sélectionné, réservée à
|
|
1022
|
+
* RECHERCHE, l'anneau orange du satellite sélectionné, réservé à STACK, et
|
|
1023
|
+
* les boutons d'action, qui ne se déploient plus en STACK. Appelé par
|
|
1024
|
+
* switchToTab — le mode se lit dans le DOM (isStackModeActive), il n'y a
|
|
1025
|
+
* donc rien à observer, seulement à resynchroniser au basculement.
|
|
1026
|
+
*/
|
|
1027
|
+
refreshModeDependentVisuals(): void;
|
|
972
1028
|
highlightOddInChildren(oddId: string | null): void;
|
|
1029
|
+
/**
|
|
1030
|
+
* Aperçu de mise en valeur d'un ODD, quelle qu'en soit l'origine : arc du
|
|
1031
|
+
* diagramme, chip de la légende du panneau RECHERCHE ou du panneau STACK.
|
|
1032
|
+
* Une sortie de survol (`null`) retombe sur l'ODD actif plutôt que
|
|
1033
|
+
* d'effacer la sélection en cours — même priorité actif/survol que celle
|
|
1034
|
+
* que YinYangDrawer applique déjà à l'arc lui-même.
|
|
1035
|
+
*/
|
|
1036
|
+
previewOddHighlight(oddId: string | null): void;
|
|
1037
|
+
/** Focus persistant — null pour l'effacer. */
|
|
1038
|
+
private setFocusedStackItem;
|
|
1039
|
+
/**
|
|
1040
|
+
* Clic sur le libellé d'un item déjà en focus, alors que son bloc est
|
|
1041
|
+
* visible dans le panneau (satellite porteur sélectionné) : désactive le
|
|
1042
|
+
* focus et retourne true — l'appelant n'a alors ni navigation ni scroll à
|
|
1043
|
+
* faire. Si le bloc n'est pas visible (l'utilisateur a navigué ailleurs
|
|
1044
|
+
* entre-temps), le clic redevient une sélection normale : false.
|
|
1045
|
+
*/
|
|
1046
|
+
toggleStackItemFocusFromStack(stackItemId: string): boolean;
|
|
1047
|
+
/** Aperçu par survol — null à la sortie, qui retombe sur le focus. */
|
|
1048
|
+
private setStackItemEmphasisPreview;
|
|
1049
|
+
/**
|
|
1050
|
+
* Point d'accroche unique de la mise en valeur du satellite source de
|
|
1051
|
+
* l'action portant l'emphase (aperçu ?? focus). Réutilise pour l'instant
|
|
1052
|
+
* le glow de highlightOddByStackItemId (ou le segment de bordure si la
|
|
1053
|
+
* source est dans une autre facette) — l'anneau animé viendra ici.
|
|
1054
|
+
* `clearIfNone` : sans emphase, efface la mise en valeur (sorties de
|
|
1055
|
+
* survol, défocus) ; false pour les simples re-applications (satellites
|
|
1056
|
+
* recréés, fin d'un survol de satellite) afin de ne pas écraser d'autres
|
|
1057
|
+
* highlights en cours.
|
|
1058
|
+
*/
|
|
1059
|
+
private applyFocusedSourceHighlight;
|
|
1060
|
+
/** Memo à une entrée de resolveEmphasisSourceChildIndex (lu chaque frame). */
|
|
1061
|
+
private _emphasisSourceMemo;
|
|
1062
|
+
/**
|
|
1063
|
+
* Index orbital du satellite source de l'action portant l'emphase, ou null
|
|
1064
|
+
* si rien ne doit être atténué : hors mode STACK (un aperçu RECHERCHE ne
|
|
1065
|
+
* doit pas hériter d'un focus STACK résiduel), item absent, Événement Clé
|
|
1066
|
+
* (pas de champ de force), ou source dans une autre facette (tout reste
|
|
1067
|
+
* plein, la bordure source est surlignée par highlightOddByStackItemId).
|
|
1068
|
+
* Résolution par oddId + cuttingIndex (buildForceFieldSourceIndicesFromStackItems),
|
|
1069
|
+
* robuste au rebuild de childOddMap ; la clé du memo suit la convention de
|
|
1070
|
+
* ForceFieldLifecycleController._buildPropCacheKey.
|
|
1071
|
+
*/
|
|
1072
|
+
private resolveEmphasisSourceChildIndex;
|
|
1073
|
+
/** Identité stable (sourceOriginKey) du satellite source d'un item de la
|
|
1074
|
+
* pile — null pour un Événement Clé ou une facette introuvable. */
|
|
1075
|
+
private _stackItemSourceOriginKey;
|
|
1076
|
+
private _emphasisKeyMemo;
|
|
1077
|
+
/** Clé de la source de l'action portant l'emphase (aperçu ?? focus), quelle
|
|
1078
|
+
* que soit sa facette ; null hors STACK ou sans emphase. Lue à chaque frame. */
|
|
1079
|
+
private resolveEmphasisSourceOriginKey;
|
|
1080
|
+
/** Memo à une entrée de resolveFocusedActionSource (lu à chaque update du menu). */
|
|
1081
|
+
private _focusSourceMemo;
|
|
1082
|
+
/**
|
|
1083
|
+
* Action en focus (focus persistant seulement, pas l'aperçu par survol —
|
|
1084
|
+
* une bulle qui apparaît/disparaît au survol serait du bruit), résolue en
|
|
1085
|
+
* (actionId, clé et index orbital du satellite source) dans la facette
|
|
1086
|
+
* courante. null hors mode STACK, sans focus, pour un Événement Clé, ou si
|
|
1087
|
+
* la source vit dans une autre facette.
|
|
1088
|
+
*/
|
|
1089
|
+
private resolveFocusedActionSource;
|
|
1090
|
+
/**
|
|
1091
|
+
* Point de départ « bulle » du champ de force de l'action en focus : la
|
|
1092
|
+
* bulle de son action dans le menu radial si le satellite source est celui
|
|
1093
|
+
* sélectionné, sinon la bulle détachée posée sur la source. null si
|
|
1094
|
+
* aucune bulle n'est visible (le champ démarre alors au satellite).
|
|
1095
|
+
*/
|
|
1096
|
+
private resolveFocusBubbleStub;
|
|
1097
|
+
private _focusLoopTimer;
|
|
1098
|
+
/** Jeton d'annulation : incrémenté à chaque (re)départ/arrêt, les passes en
|
|
1099
|
+
* vol comparent leur jeton à chaque frame et s'effacent si dépassées. */
|
|
1100
|
+
private _focusLoopRun;
|
|
1101
|
+
/** Pause entre deux passes (propagationCometConfig.loopGapMs, panneau
|
|
1102
|
+
* Debug). Un timer en attente est reposé avec la nouvelle valeur pour que
|
|
1103
|
+
* le réglage se sente tout de suite. */
|
|
1104
|
+
setFocusPropagationLoopGapMs(ms: number): void;
|
|
1105
|
+
private restartFocusPropagationLoop;
|
|
1106
|
+
private stopFocusPropagationLoop;
|
|
1107
|
+
private _runFocusPropagationLoopPass;
|
|
1108
|
+
/** Liens sortants par index orbital de départ (segments chaînés inclus),
|
|
1109
|
+
* restreints à ceux qui mènent quelque part (satellite ou autre facette). */
|
|
1110
|
+
private _buildOutgoingLinkMap;
|
|
1111
|
+
/** Tous les chemins `prefix` + descente depuis `node` jusqu'aux feuilles
|
|
1112
|
+
* (satellite sans lien sortant, ou arc d'une autre facette), sans cycle. */
|
|
1113
|
+
private _walkPropagationPaths;
|
|
1114
|
+
/** Anime simultanément chaque chemin (waypoints `head` puis la cible de
|
|
1115
|
+
* chaque lien) ; retourne la durée de la passe la plus longue. */
|
|
1116
|
+
private _animatePropagationPaths;
|
|
1117
|
+
/**
|
|
1118
|
+
* Joue une passe de propagation sur l'arbre complet des champs de force
|
|
1119
|
+
* d'une source de la facette courante : chaque chemin racine → feuille est
|
|
1120
|
+
* animé simultanément, comme le clic sur l'en-tête d'un bloc source.
|
|
1121
|
+
* L'arbre est lu dans state.forceField.links via le tag sourceChildIndex
|
|
1122
|
+
* (segments chaînés inclus : startIndex = cible précédente). La comète part
|
|
1123
|
+
* de la bulle d'action quand elle est visible. Retourne la durée de la
|
|
1124
|
+
* passe (0 si rien à animer).
|
|
1125
|
+
*/
|
|
1126
|
+
private flashSourcePropagationTree;
|
|
1127
|
+
/**
|
|
1128
|
+
* Même passe pour une action dont la source vit dans une autre facette :
|
|
1129
|
+
* ses liens entrants ici (tagués sourceOriginKey, recopié par
|
|
1130
|
+
* restoreIncomingForceFieldContext) partent de l'arc de la facette source ;
|
|
1131
|
+
* chaque entrée est prolongée par sa cascade intra-facette. Retourne la
|
|
1132
|
+
* durée de la passe (0 si cette action n'a aucun lien entrant ici).
|
|
1133
|
+
*/
|
|
1134
|
+
private flashIncomingPropagationTree;
|
|
973
1135
|
highlightOddByStackItemId(stackItemId: string | null): void;
|
|
974
1136
|
/**
|
|
975
1137
|
* Retourne les actions applicables au cutting associé à `childKey`,
|
|
@@ -14,6 +14,9 @@ export declare class ActionStackController {
|
|
|
14
14
|
private fallingStackItemIds;
|
|
15
15
|
private keyboardListenersBound;
|
|
16
16
|
private _linkedHoverId;
|
|
17
|
+
/** Item en focus (action en focus côté panneau) : style persistant,
|
|
18
|
+
* synchronisé par YinYangController.setFocusedStackItem. */
|
|
19
|
+
private _focusedItemId;
|
|
17
20
|
private _onBlockHighlightCb?;
|
|
18
21
|
private _onSatelliteHighlightCb?;
|
|
19
22
|
private activeComboHighlight;
|
|
@@ -50,6 +53,18 @@ export declare class ActionStackController {
|
|
|
50
53
|
setSatelliteHighlightCallback(cb: (id: string | null) => void): void;
|
|
51
54
|
getItemById(id: string): ActionStackItem | undefined;
|
|
52
55
|
highlightByStackItemId(id: string | null): void;
|
|
56
|
+
/** Focus persistant (miroir du bloc en focus dans le panneau) — survit aux
|
|
57
|
+
* re-rendus, updateVisual relisant _focusedItemId. */
|
|
58
|
+
setFocusedItemId(id: string | null): void;
|
|
59
|
+
/**
|
|
60
|
+
* Style du cadre d'un item selon son emphase, par priorité décroissante :
|
|
61
|
+
* survol lié (aperçu) > focus (persistant, teinte pleine + halo) > coché
|
|
62
|
+
* (halo discret) > repos. Source unique pour updateVisual,
|
|
63
|
+
* highlightByStackItemId et setFocusedItemId, afin qu'un re-rendu ne
|
|
64
|
+
* fasse jamais retomber le focus.
|
|
65
|
+
*/
|
|
66
|
+
private _hitboxEmphasisStyle;
|
|
67
|
+
private _applyHitboxEmphasisStyles;
|
|
53
68
|
/**
|
|
54
69
|
* Affiche temporairement le highlight combo (cercles de fenêtre) pendant ~1.8 s.
|
|
55
70
|
* Sans effet si un highlight permanent est déjà actif.
|
|
@@ -3,6 +3,17 @@ import { IYinYangView } from "../../../interfaces/IYinYangView";
|
|
|
3
3
|
import { type ActionDefinition } from "../../../data/yasuni_actions";
|
|
4
4
|
import { ChildrenOrbitEntry } from "../utils/childrenOrbit";
|
|
5
5
|
import { type Point } from "./radialItemMenu";
|
|
6
|
+
type DetachedBubbleContext = {
|
|
7
|
+
orbitData: ChildrenOrbitEntry[];
|
|
8
|
+
/** Satellite source porteur de la bulle — null = aucune bulle détachée. */
|
|
9
|
+
sourceChildKey: string | null;
|
|
10
|
+
action: ActionDefinition | null;
|
|
11
|
+
childActionMenuItemDistance: number;
|
|
12
|
+
childActionMenuItemScale: number;
|
|
13
|
+
childActionIconFontScale: number;
|
|
14
|
+
/** Clic sur la bulle : typiquement, sélectionner le satellite source. */
|
|
15
|
+
onClick: (sourceChildKey: string, actionId: string) => void;
|
|
16
|
+
};
|
|
6
17
|
type ChildActionMenuContext = {
|
|
7
18
|
orbitData: ChildrenOrbitEntry[];
|
|
8
19
|
activeActionMenuChildKey: string | null;
|
|
@@ -44,6 +55,18 @@ export declare class ChildActionMenuController {
|
|
|
44
55
|
* le contexte courant) et rejoué au survol : rallumer une impulsion ne
|
|
45
56
|
* doit pas relancer la chorégraphie d'ouverture. */
|
|
46
57
|
private linkStyleGetter;
|
|
58
|
+
/** Positions du dernier update() — exposées au champ de force (le segment
|
|
59
|
+
* « bulle → source » démarre au centre de la bulle de l'action en focus). */
|
|
60
|
+
private lastPositions;
|
|
61
|
+
private detachedGroup;
|
|
62
|
+
private detachedLineLayer;
|
|
63
|
+
private lastDetachedCenter;
|
|
64
|
+
private lastDetachedPosition;
|
|
65
|
+
/** Centre (coordonnées du globalGroup) de la bulle `actionId` du menu radial
|
|
66
|
+
* ouvert, ou null si elle n'y est pas. */
|
|
67
|
+
getItemCenter(actionId: string): Point | null;
|
|
68
|
+
/** Centre de la bulle détachée si elle porte `actionId`, sinon null. */
|
|
69
|
+
getDetachedCenter(actionId: string): Point | null;
|
|
47
70
|
constructor(view: IYinYangView, getChildRenderedCenter: (childController: IYinYangController) => Point | null, refreshActionStackVisual: () => void,
|
|
48
71
|
/** Aperçu — 1er clic sur une action : affiche sa carte, ne joue rien. */
|
|
49
72
|
activateActionFromChild: (childController: IYinYangController, actionId: string, label?: string) => void,
|
|
@@ -69,6 +92,9 @@ export declare class ChildActionMenuController {
|
|
|
69
92
|
private setHoveredAction;
|
|
70
93
|
retractAndDispose(): void;
|
|
71
94
|
clearImmediately(): void;
|
|
95
|
+
/** Retire la bulle détachée et son faisceau, tout de suite (0) ou après un
|
|
96
|
+
* délai (fin d'une transition de facette). */
|
|
97
|
+
private disposeDetached;
|
|
72
98
|
/**
|
|
73
99
|
* Starts the fold-out animation on the visible action buttons, then removes
|
|
74
100
|
* the group once every item has finished animating. Nulls the group
|
|
@@ -76,6 +102,20 @@ export declare class ChildActionMenuController {
|
|
|
76
102
|
* that follows is a no-op and won't cancel the in-flight transition.
|
|
77
103
|
*/
|
|
78
104
|
animateClose(): void;
|
|
105
|
+
/** Replie la bulle détachée (chorégraphie de fermeture), groupes conservés. */
|
|
106
|
+
private closeDetached;
|
|
107
|
+
/**
|
|
108
|
+
* Bulle détachée de l'action en focus : quand un bloc de propagation est
|
|
109
|
+
* en focus, le satellite sélectionné n'est pas la source et son menu ne
|
|
110
|
+
* montre donc pas la bulle de l'action. On pose alors, sur le satellite
|
|
111
|
+
* source, la seule bulle de cette action (pas ses sœurs), en style
|
|
112
|
+
* « regardée », avec son faisceau — le champ de force peut ainsi toujours
|
|
113
|
+
* démarrer à la bulle. Un clic sélectionne le satellite source (le menu
|
|
114
|
+
* complet prend alors le relais et la bulle détachée se replie).
|
|
115
|
+
* Cluster indépendant du menu radial : update() n'en sait rien.
|
|
116
|
+
*/
|
|
117
|
+
updateDetached(context: DetachedBubbleContext): void;
|
|
118
|
+
private ensureDetachedGroups;
|
|
79
119
|
update(context: ChildActionMenuContext): void;
|
|
80
120
|
private ensureChildActionMenuGroup;
|
|
81
121
|
private ensureLineLayer;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { IYinYangController } from "../../../interfaces/IYinYangController";
|
|
2
2
|
import { IYinYangView } from "../../../interfaces/IYinYangView";
|
|
3
3
|
import { YinYangInternalModel } from "../../../interfaces/IYinYangInternalModel";
|
|
4
|
+
import { ChildHighlightState } from "../odd/childHighlightStyles";
|
|
4
5
|
type ChildOddMeta = {
|
|
5
6
|
oddId: string;
|
|
6
7
|
score: number;
|
|
@@ -19,6 +20,11 @@ type ChildInteractionControllerDeps = {
|
|
|
19
20
|
onUserCuttingClicked?: (childController: IYinYangController) => void;
|
|
20
21
|
/** Appelé quand la souris entre/sort d'un satellite (null = sortie). */
|
|
21
22
|
onChildHover?: (oddId: string | null, cuttingIndex?: number) => void;
|
|
23
|
+
/** ODD actuellement mis en valeur (OddViewManager) — le style "satellite
|
|
24
|
+
* actif" et le survol doivent le respecter au lieu de l'écraser. */
|
|
25
|
+
getOddHighlight: () => ChildHighlightState;
|
|
26
|
+
/** Satellites atteints par la propagation de l'action en cours. */
|
|
27
|
+
getPropagationTargetKeys: () => Set<string>;
|
|
22
28
|
};
|
|
23
29
|
export declare class ChildInteractionController {
|
|
24
30
|
private deps;
|
|
@@ -33,6 +39,9 @@ export declare class ChildInteractionController {
|
|
|
33
39
|
clearActiveChild(childControllers: IYinYangController[]): void;
|
|
34
40
|
animateChildren(childControllers: IYinYangController[], show: boolean, onBeforeShow?: () => void, onBeforeHide?: () => void): Promise<void>;
|
|
35
41
|
private applyChildActiveStyle;
|
|
42
|
+
/** Filtre courant d'un satellite : la mise en valeur d'un ODD prime sur le
|
|
43
|
+
* style "actif", qui prime lui-même sur l'état neutre. */
|
|
44
|
+
private resolveFilterFor;
|
|
36
45
|
private getChildOffset;
|
|
37
46
|
}
|
|
38
47
|
export {};
|
|
@@ -123,12 +123,25 @@ export declare class ForceFieldDetailsPanel {
|
|
|
123
123
|
private _onDiagramElementHover?;
|
|
124
124
|
/** Called when hovering a cumulative block — notifies the stack to highlight the matching item. */
|
|
125
125
|
private _onStackItemHighlightCb?;
|
|
126
|
+
/** Clic sur l'en-tête d'un bloc → action en focus (YinYangController). */
|
|
127
|
+
private _onStackItemFocusCb?;
|
|
128
|
+
/** Miroir de state.forceField.focusedStackItemId — sert uniquement à
|
|
129
|
+
* ré-appliquer .ff-block--focused après chaque innerHTML. */
|
|
130
|
+
private _focusedStackItemId;
|
|
131
|
+
/** Bloc actuellement survolé — pour détecter un survol orphelin quand le
|
|
132
|
+
* bloc est détruit par un re-rendu sans que mouseleave n'ait été émis. */
|
|
133
|
+
private _hoveredBlockStackItemId;
|
|
126
134
|
/** Id d'un bloc "Effets cumulés" à centrer (scroll animé) dès qu'il apparaît
|
|
127
135
|
* dans le panneau — voir requestScrollToStackItemBlock. Le rendu déclencheur
|
|
128
136
|
* (renderComposanteInfo / renderCumulativeActionDetails) peut survenir de
|
|
129
137
|
* façon asynchrone après la demande (ouverture animée du satellite). */
|
|
130
138
|
private _pendingBlockScrollStackItemId;
|
|
131
139
|
private _pendingBlockScrollTimeout;
|
|
140
|
+
/** Dernier bloc ciblé par un clic-libellé de la pile — encadré persistant
|
|
141
|
+
* (.ff-block--selected) pour savoir à tout instant quel bloc est sélectionné,
|
|
142
|
+
* là où le focus-flash s'éteint en fin d'animation. Remplacé au prochain
|
|
143
|
+
* clic-libellé ; ré-appliqué après chaque innerHTML comme le focus. */
|
|
144
|
+
private _selectedStackItemId;
|
|
132
145
|
/** Notifie le header (chip STACK) du badge + nom de l'élément affiché par les
|
|
133
146
|
* cartes d'info minimales (Sphère, ODD) — ces cartes ne répètent plus ce
|
|
134
147
|
* titre dans leur corps. Facette et Satellite restent gérés par leurs
|
|
@@ -166,11 +179,13 @@ export declare class ForceFieldDetailsPanel {
|
|
|
166
179
|
* celle d'une tout autre carte, ou une position absente du snapshot
|
|
167
180
|
* précédent, ce qui la replierait par défaut au lieu de suivre l'auto-fit. */
|
|
168
181
|
private _hasStableCardKey;
|
|
169
|
-
/** Un clic "
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
182
|
+
/** Un clic "poignée" (ouvrir/replier la carte, rien d'autre — pas de flash
|
|
183
|
+
* de propagation, pas de surlignage combo) : le badge delta en haut à
|
|
184
|
+
* droite, le chip de poids, et l'en-tête de la carte — même rôle pour tous
|
|
185
|
+
* les types de cartes. L'en-tête portait autrefois le flash de propagation
|
|
186
|
+
* des cartes source ; ce flash tourne désormais en boucle sur l'action en
|
|
187
|
+
* focus (YinYangController.flashSourcePropagationTree) et reste accessible
|
|
188
|
+
* ligne par ligne dans le corps de la carte. */
|
|
174
189
|
private _isCardCollapseTrigger;
|
|
175
190
|
private _attachComboHighlightHandlers;
|
|
176
191
|
/** Contexte combo (backward) ou amplificateur (forward) déduit de
|
|
@@ -289,10 +304,16 @@ export declare class ForceFieldDetailsPanel {
|
|
|
289
304
|
* bloc combo/amplificateur, pour que ce bloc-ci ne fasse pas exception.
|
|
290
305
|
*/
|
|
291
306
|
private _buildDelayedTargetsCardHtml;
|
|
292
|
-
/** Badge et note de provenance d'un bloc action de la vue cumulative
|
|
293
|
-
* propagée
|
|
294
|
-
*
|
|
307
|
+
/** Badge et note de provenance d'un bloc action de la vue cumulative.
|
|
308
|
+
* Seule une action propagée porte une note dans l'en-tête (le satellite
|
|
309
|
+
* dont elle provient) : pour une action directe — adverse comprise — on
|
|
310
|
+
* est déjà sur le satellite porteur, l'information serait redondante.
|
|
311
|
+
* L'acteur d'origine d'une action adverse est rendu à part (`origin`),
|
|
312
|
+
* dans le corps du bloc, pour ne pas concurrencer le nom. */
|
|
295
313
|
private _pickActionBlockBadge;
|
|
314
|
+
/** Ligne « Acteur : … » placée en tête du corps d'un bloc adverse (action
|
|
315
|
+
* ou Événement) — remplace l'ancienne note d'en-tête. */
|
|
316
|
+
private _buildBlockOriginHtml;
|
|
296
317
|
/**
|
|
297
318
|
* En-tête générique et repliable d'un .ff-cumulative-block — icône, badge
|
|
298
319
|
* de type, nom, note de provenance optionnelle ("rationale"), et une
|
|
@@ -461,6 +482,20 @@ export declare class ForceFieldDetailsPanel {
|
|
|
461
482
|
}): void;
|
|
462
483
|
private _attachBlockLinkedHoverHandlers;
|
|
463
484
|
setStackItemHighlightCallback(cb: (id: string | null) => void): void;
|
|
485
|
+
/** Vrai si le panneau affiche actuellement le bloc « Effets cumulés » de cet
|
|
486
|
+
* item de pile (le satellite/la facette porteuse est sélectionné). */
|
|
487
|
+
hasBlockForStackItem(stackItemId: string): boolean;
|
|
488
|
+
setStackItemFocusCallback(cb: (id: string | null) => void): void;
|
|
489
|
+
/** Miroir du focus (source de vérité : YinYangController / state). */
|
|
490
|
+
setFocusedStackItemId(id: string | null): void;
|
|
491
|
+
/**
|
|
492
|
+
* Ré-applique .ff-block--focused sur le bloc en focus — à appeler après
|
|
493
|
+
* chaque rendu de blocs (innerHTML), comme _consumePendingBlockScroll.
|
|
494
|
+
* Profite du passage pour clore un survol orphelin : un bloc survolé puis
|
|
495
|
+
* détruit par le re-rendu n'émet jamais mouseleave, et son aperçu
|
|
496
|
+
* primerait indéfiniment sur le focus.
|
|
497
|
+
*/
|
|
498
|
+
private _applyFocusedBlockClass;
|
|
464
499
|
highlightBlockByStackItemId(id: string | null): void;
|
|
465
500
|
/**
|
|
466
501
|
* Demande de centrer (scroll animé) le bloc "Effets cumulés" de cet item de
|
|
@@ -475,6 +510,22 @@ export declare class ForceFieldDetailsPanel {
|
|
|
475
510
|
*/
|
|
476
511
|
requestScrollToStackItemBlock(stackItemId: string): void;
|
|
477
512
|
private _consumePendingBlockScroll;
|
|
513
|
+
/**
|
|
514
|
+
* Déplie la carte source du premier rail d'un bloc — même désignation que
|
|
515
|
+
* _applyAutoFitToGrids (carte marquée source, sinon premier non-combo), qui
|
|
516
|
+
* ne la replie jamais quelle que soit la phase : l'ouvrir ici ne sera donc
|
|
517
|
+
* pas défait par l'auto-fit déclenché ensuite (rAF / ResizeObserver). Si le
|
|
518
|
+
* rail déborde, il scrolle — comme après un clic utilisateur sur la carte.
|
|
519
|
+
*/
|
|
520
|
+
private _expandSourceCard;
|
|
521
|
+
/**
|
|
522
|
+
* Mise en valeur appuyée (halo pulsé aux couleurs de l'item, cf.
|
|
523
|
+
* .ff-block--focus-flash) du bloc que le clic-libellé vient de centrer, pour
|
|
524
|
+
* qu'il se distingue nettement de ses voisins une fois le scroll terminé.
|
|
525
|
+
* La classe est retirée en fin d'animation ; un nouveau focus sur le même
|
|
526
|
+
* bloc relance l'animation depuis le début (retrait + reflow + ré-ajout).
|
|
527
|
+
*/
|
|
528
|
+
private _flashFocusedBlock;
|
|
478
529
|
private getTargetName;
|
|
479
530
|
private getGhostDetailsContainer;
|
|
480
531
|
private getForceFieldDetailsContainer;
|
|
@@ -35,6 +35,23 @@ type ForceFieldLifecycleControllerDeps = {
|
|
|
35
35
|
x: number;
|
|
36
36
|
y: number;
|
|
37
37
|
} | null;
|
|
38
|
+
/** Index orbital du satellite source de l'action en focus/aperçu (voir
|
|
39
|
+
* YinYangController.resolveEmphasisSourceChildIndex), null sans emphase.
|
|
40
|
+
* Lu à chaque frame : le renderer lisse lui-même la transition. */
|
|
41
|
+
getEmphasisSourceChildIndex: () => number | null;
|
|
42
|
+
/** Identité (sourceOriginKey) du satellite source de l'action en
|
|
43
|
+
* focus/aperçu, même quand il vit dans une autre facette — c'est elle qui
|
|
44
|
+
* atténue les liens entrants des autres actions. null sans emphase. */
|
|
45
|
+
getEmphasisSourceOriginKey: () => string | null;
|
|
46
|
+
/** Bulle d'action de l'action en focus (menu radial du satellite source,
|
|
47
|
+
* ou bulle détachée) — le champ de cette source démarre à la bulle. */
|
|
48
|
+
getFocusBubbleStub: () => {
|
|
49
|
+
sourceChildIndex: number;
|
|
50
|
+
center: {
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
};
|
|
54
|
+
} | null;
|
|
38
55
|
};
|
|
39
56
|
export declare class ForceFieldLifecycleController {
|
|
40
57
|
private deps;
|
|
@@ -22,16 +22,41 @@ export declare class ForceFieldRenderer {
|
|
|
22
22
|
* Called by YinYangController while the propagation arc travels the matching segment.
|
|
23
23
|
*/
|
|
24
24
|
pulseLink(linkIndex: number, durationMs: number): void;
|
|
25
|
+
/** Horodatage du dernier updateVisual — updateVisual ne reçoit pas de Δt,
|
|
26
|
+
* on le dérive ici pour le lissage de l'emphase. */
|
|
27
|
+
private _lastVisualNow;
|
|
28
|
+
/** Identité du segment « bulle → source » courant et origine de sa
|
|
29
|
+
* révélation (voir updateVisual / bubbleStub). */
|
|
30
|
+
private _stubKey;
|
|
31
|
+
private _stubRevealAt;
|
|
25
32
|
hasActiveGroup(): boolean;
|
|
26
33
|
ensureElements(params: {
|
|
27
34
|
globalGroupNode: SVGGElement;
|
|
28
35
|
requiredCount: number;
|
|
29
36
|
}): void;
|
|
37
|
+
/** Ajuste le nombre de layers au nombre de segments à dessiner (liens +
|
|
38
|
+
* éventuel segment « bulle → source », voir updateVisual). */
|
|
39
|
+
private _ensureLayerCount;
|
|
30
40
|
updateVisual(params: {
|
|
31
41
|
forceFieldOrbitData: ChildrenOrbitEntry[] | null;
|
|
32
42
|
forceFieldLinks: ForceFieldSegment[];
|
|
33
43
|
forceFieldRevealStartedAt?: number;
|
|
34
44
|
forceFieldPhase: number;
|
|
45
|
+
/** Index orbital du satellite source de l'action en focus (ou en aperçu
|
|
46
|
+
* par survol) ; null = pas d'emphase, tous les liens restent pleins. */
|
|
47
|
+
emphasisSourceChildIndex: number | null;
|
|
48
|
+
/** Identité stable (sourceOriginKey) de la source de l'action en
|
|
49
|
+
* focus/aperçu — prime sur l'index quand le lien la porte, et seule
|
|
50
|
+
* façon d'atténuer les liens entrants (source dans une autre facette). */
|
|
51
|
+
emphasisSourceOriginKey: string | null;
|
|
52
|
+
/** Bulle d'action de l'action en focus : quand elle est connue, le champ
|
|
53
|
+
* de cette source « démarre » à la bulle — un segment supplémentaire
|
|
54
|
+
* bulle → satellite source est dessiné avec la grammaire des liens
|
|
55
|
+
* (port d'émission à la bulle, éclat au satellite). null = aucun. */
|
|
56
|
+
bubbleStub: {
|
|
57
|
+
sourceChildIndex: number;
|
|
58
|
+
center: Point;
|
|
59
|
+
} | null;
|
|
35
60
|
getChildRenderedCenter: (childController: IYinYangController) => Point | null;
|
|
36
61
|
getComponentBorderTargetPoint: (componentId: string) => Point | null;
|
|
37
62
|
}): void;
|
|
@@ -31,8 +31,24 @@ export type ForceFieldLink = {
|
|
|
31
31
|
potentialGain: number;
|
|
32
32
|
/** Delay before revealing this link, used for chained intra-ODD propagation. */
|
|
33
33
|
revealDelayMs?: number;
|
|
34
|
+
/** Index orbital du satellite source racine ayant produit ce lien (posé par
|
|
35
|
+
* ForceFieldComputationService.build, un appel par source). Pour un segment
|
|
36
|
+
* chaîné, startIndex est la cible précédente : seul ce champ dit à quelle
|
|
37
|
+
* action le lien appartient — c'est la clé de l'emphase par action en focus
|
|
38
|
+
* (ForceFieldRenderer). Absent pour les liens injectés en incomingMode
|
|
39
|
+
* (buildFromSource) → jamais atténués. */
|
|
40
|
+
sourceChildIndex?: number;
|
|
41
|
+
/** Identité stable du satellite source racine de l'action (voir
|
|
42
|
+
* buildSourceOriginKey). Contrairement à sourceChildIndex (index orbital,
|
|
43
|
+
* local à une facette), elle survit au changement de facette : recopiée
|
|
44
|
+
* sur les liens entrants (restoreIncomingForceFieldContext), elle permet à
|
|
45
|
+
* l'emphase et à la comète de l'action en focus de suivre sa propagation
|
|
46
|
+
* inter-facettes depuis l'arc de la facette source. */
|
|
47
|
+
sourceOriginKey?: string;
|
|
34
48
|
detail: ForceFieldLinkDetail;
|
|
35
49
|
};
|
|
50
|
+
/** Clé d'identité d'un satellite source racine : `composante|odd|cutting`. */
|
|
51
|
+
export declare function buildSourceOriginKey(componentId: string, oddId: string, cuttingId: number | undefined): string;
|
|
36
52
|
/**
|
|
37
53
|
* Représentation pure-rendu d'un segment de champ de force.
|
|
38
54
|
* Identique à ForceFieldLink mais sans le champ `detail` (domaine métier).
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/** Un satellite membre de l'ODD mis en valeur, dans le repère du globalGroup
|
|
2
|
+
* de la facette parente (mêmes coordonnées que
|
|
3
|
+
* WeightPreviewRingRenderer : centre orbital courant + rayon du satellite). */
|
|
4
|
+
export type OddHighlightTarget = {
|
|
5
|
+
id: string;
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
radius: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Effets "sélection d'ODD" posés sur les satellites membres, dans le
|
|
12
|
+
* globalGroup de la facette parente — donc dans le même repère que les
|
|
13
|
+
* satellites eux-mêmes, qui continuent d'orbiter dessous (les positions sont
|
|
14
|
+
* relues à chaque frame via `getTargets`, jamais figées à la construction).
|
|
15
|
+
*
|
|
16
|
+
* Trois couches, toutes peintes dans la couleur de l'ODD :
|
|
17
|
+
* - un anneau de visée pointillé dont les tirets dérivent lentement,
|
|
18
|
+
* doublé de quatre crochets d'angle qui tournent en sens inverse ;
|
|
19
|
+
* - un "ping" sonar qui s'échappe de chaque satellite en boucle, décalé
|
|
20
|
+
* d'un satellite à l'autre ;
|
|
21
|
+
* - une onde de scan unique partant de la couronne de la facette, tirée une
|
|
22
|
+
* seule fois quand un nouvel ODD passe en sélection (voir `oddKey`).
|
|
23
|
+
*
|
|
24
|
+
* Réservé à l'intensité "full" (clic) : le survol n'allume que le halo
|
|
25
|
+
* coloré des satellites, sans rien de tout ceci — voir OddViewManager.
|
|
26
|
+
*
|
|
27
|
+
* Aucun filtre CSS ici, à dessein : un `drop-shadow` sur un élément dont
|
|
28
|
+
* un attribut change à chaque frame (rotation des crochets, dérive des
|
|
29
|
+
* tirets, rayon du ping) force une passe de flou par frame et par élément —
|
|
30
|
+
* mesuré à 65 ms/frame avec cinq satellites en orbite. La lueur est rendue
|
|
31
|
+
* par un second trait, plus large et translucide, dessiné sous le trait
|
|
32
|
+
* net : même lecture, coût nul. De même, les styles constants ne sont posés
|
|
33
|
+
* qu'à la création (enter), seule la géométrie est écrite par frame.
|
|
34
|
+
*/
|
|
35
|
+
export declare class OddHighlightEffects {
|
|
36
|
+
private layerNode;
|
|
37
|
+
private getTargets;
|
|
38
|
+
private color;
|
|
39
|
+
private frameId;
|
|
40
|
+
private scan;
|
|
41
|
+
/** ODD actuellement mis en valeur — sert à ne retirer l'onde de scan
|
|
42
|
+
* qu'une seule fois par sélection, et non à chaque re-render. */
|
|
43
|
+
private currentOddKey;
|
|
44
|
+
render(params: {
|
|
45
|
+
globalGroupNode: SVGGElement | null;
|
|
46
|
+
getTargets: () => OddHighlightTarget[];
|
|
47
|
+
color: string;
|
|
48
|
+
oddKey: string;
|
|
49
|
+
parentCenterX: number;
|
|
50
|
+
/** Rayon de départ de l'onde de scan : le bord externe de la couronne,
|
|
51
|
+
* et non le centre — la moitié intérieure de la course serait cachée
|
|
52
|
+
* sous le disque de la facette, et l'onde doit se lire comme partant de
|
|
53
|
+
* l'arc de l'ODD vers ses satellites. */
|
|
54
|
+
parentCenterY: number;
|
|
55
|
+
scanStartRadius: number;
|
|
56
|
+
scanRadius: number;
|
|
57
|
+
}): void;
|
|
58
|
+
/**
|
|
59
|
+
* Retire toutes les couches. `keepOddMemory` conserve l'ODD mémorisé pour
|
|
60
|
+
* la déduplication de l'onde de scan : on l'utilise quand la mise en
|
|
61
|
+
* valeur n'est que *rétrogradée* en "soft" (survol d'un arc voisin alors
|
|
62
|
+
* qu'un ODD est sélectionné) — sinon le simple fait de repasser la souris
|
|
63
|
+
* rejouerait l'onde à chaque retour sur la sélection.
|
|
64
|
+
*/
|
|
65
|
+
clear(keepOddMemory?: boolean): void;
|
|
66
|
+
private ensureLayer;
|
|
67
|
+
private ensureLoop;
|
|
68
|
+
private stopLoop;
|
|
69
|
+
/** Jointure d'un couple lueur + trait net pour une forme donnée : la lueur
|
|
70
|
+
* est le même élément, dessiné d'abord, plus large et translucide. */
|
|
71
|
+
private joinPair;
|
|
72
|
+
private drawReticles;
|
|
73
|
+
/** Quatre arcs courts aux diagonales — le "target lock" qui encadre
|
|
74
|
+
* l'anneau de visée sans le fermer. */
|
|
75
|
+
private buildBracketPath;
|
|
76
|
+
private drawPings;
|
|
77
|
+
private drawScan;
|
|
78
|
+
}
|