@micheeeeel/yinyangapp 2.0.4 → 2.1.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 +18 -0
- package/dist/bundle.js +1 -1
- package/dist/types/adapters/yasuniCauseAdapter.d.ts +12 -0
- package/dist/types/animations/AnimationsMngr.d.ts +49 -2
- package/dist/types/animations/fastHomingStop.d.ts +57 -0
- package/dist/types/animations/fastHomingStop.test.d.ts +1 -0
- package/dist/types/api-film.d.ts +7 -0
- package/dist/types/api-random.d.ts +32 -0
- package/dist/types/api-random.test.d.ts +1 -0
- package/dist/types/api.d.ts +3 -0
- package/dist/types/components/controller/YinYangController.d.ts +24 -1
- package/dist/types/components/controller/odd/ChildrenOrbitManager.d.ts +51 -3
- package/dist/types/components/controls/VizControlsPanel.d.ts +2 -0
- package/dist/types/components/view/YinYangDrawer.d.ts +33 -0
- package/dist/types/config/animationConfig.d.ts +7 -0
- package/dist/types/interfaces/IYinYangController.d.ts +13 -1
- package/dist/types/utils/InactivityTracker.d.ts +25 -0
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Composante } from "../data/yasuni_cause";
|
|
2
|
+
import type { Cause } from "../interfaces/ICauseModel";
|
|
3
|
+
/**
|
|
4
|
+
* Adapte le catalogue Composante[] (format yasuni_cause.ts) vers le format
|
|
5
|
+
* Cause attendu par validateCauseGraph et mapCauseToInternalModel.
|
|
6
|
+
* Les scores initiaux sont neutres (0.5 = 50 % de tension), les poids valent 1
|
|
7
|
+
* par satellite tant qu'aucune valeur n'est renseignée dans les données.
|
|
8
|
+
*/
|
|
9
|
+
export declare function composantesToCause(composantes: Composante[], id?: string, name?: string): Cause;
|
|
10
|
+
/** La `Cause` du Yasuní, fraîchement construite à chaque appel (l'hôte peut
|
|
11
|
+
* la muter sans effet de bord). `id` par défaut : "yasuni". */
|
|
12
|
+
export declare function getYasuniCause(id?: string): Cause;
|
|
@@ -5,9 +5,56 @@ export declare class AnimationsMngr {
|
|
|
5
5
|
startAll(): void;
|
|
6
6
|
setRotationDuration(durationMs: number): void;
|
|
7
7
|
revertRotation(component: IYinYangController): void;
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Arrête la rotation. Avec `rampMs > 0` et une rotation en cours, le
|
|
10
|
+
* yin-yang continue sa course et décélère à taux constant pour s'arrêter
|
|
11
|
+
* exactement sur sa position de base (angle multiple de 360°) — voir
|
|
12
|
+
* `beginHomingStop`. `rampMs` omis (0) ou aucune rotation active → arrêt
|
|
13
|
+
* immédiat, comportement historique (utilisé tel quel par le benchmark et
|
|
14
|
+
* les changements de composant).
|
|
15
|
+
*/
|
|
16
|
+
stopRotation(component: IYinYangController, rampMs?: number): void;
|
|
17
|
+
/**
|
|
18
|
+
* Arrête la rotation en rejoignant la position de base dans une durée
|
|
19
|
+
* FIXE `durationMs`, quelle que soit la distance restante — troisième mode
|
|
20
|
+
* d'arrêt, entre l'instantané (`rampMs=0`) et le freinage "confort"
|
|
21
|
+
* (`stopRotation` avec `rampMs>0`, qui peut faire durer l'arrêt jusqu'à
|
|
22
|
+
* near un tour complet). Voir `beginFastHomingStop`.
|
|
23
|
+
*/
|
|
24
|
+
stopRotationFast(component: IYinYangController, durationMs: number): void;
|
|
25
|
+
/**
|
|
26
|
+
* Calibre un freinage à décélération constante qui ramène la rotation
|
|
27
|
+
* exactement sur un multiple de 360° (donc visuellement sur la position de
|
|
28
|
+
* base) au moment précis où la vitesse atteint 0 — pas de saut final.
|
|
29
|
+
*
|
|
30
|
+
* On vise en priorité le prochain passage par la position de base dans le
|
|
31
|
+
* sens courant (distance `remainingToZero`, 0 à 360°). Si cette distance
|
|
32
|
+
* est trop courte pour freiner en douceur à la vitesse actuelle (durée
|
|
33
|
+
* naturelle < `rampMs`, ce qui donnerait un freinage brutal), on fait
|
|
34
|
+
* plutôt un tour de plus (`+360°`) pour laisser le temps de décélérer
|
|
35
|
+
* confortablement — `rampMs` sert donc de plancher de confort, pas d'une
|
|
36
|
+
* durée cible stricte : la distance à parcourir pour retomber pile sur la
|
|
37
|
+
* position de base prime.
|
|
38
|
+
*/
|
|
39
|
+
private beginHomingStop;
|
|
40
|
+
/**
|
|
41
|
+
* Calibre un freinage qui rejoint TOUJOURS le prochain passage par la
|
|
42
|
+
* position de base dans le sens courant (jamais de tour supplémentaire —
|
|
43
|
+
* contrairement à `beginHomingStop`), dans la durée fixe `durationMs`
|
|
44
|
+
* choisie par l'utilisateur — voir `computeFastStopProfile`.
|
|
45
|
+
*/
|
|
46
|
+
private beginFastHomingStop;
|
|
47
|
+
private finalizeStop;
|
|
9
48
|
private resetRotationFrame;
|
|
10
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Démarre (ou modifie en vol) la rotation. Avec `rampMs > 0`, la vitesse
|
|
51
|
+
* angulaire part de sa valeur courante (0 si à l'arrêt) et chasse
|
|
52
|
+
* progressivement la vitesse cible déduite de `time`/`clockWise` — un appel
|
|
53
|
+
* pendant qu'un arrêt progressif est en cours ré-accélère en douceur depuis
|
|
54
|
+
* la vitesse déjà atteinte, sans à-coup. `rampMs` omis (0) → vitesse cible
|
|
55
|
+
* appliquée instantanément, comportement historique.
|
|
56
|
+
*/
|
|
57
|
+
animate(component: IYinYangController, clockWise: boolean, time?: number, rampMs?: number): void;
|
|
11
58
|
private startRotationLoop;
|
|
12
59
|
private applyRotationFrame;
|
|
13
60
|
private applyRotationToYinYangGroup;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calcule un profil de vitesse qui ramène une rotation (spin ou orbite) pile
|
|
3
|
+
* sur sa position de base — distance `distance` (>0, dans le sens courant) —
|
|
4
|
+
* dans une durée totale FIXE `targetDurationMs` choisie par l'utilisateur,
|
|
5
|
+
* quelle que soit cette distance. C'est le troisième mode d'arrêt ("Accéléré")
|
|
6
|
+
* : contrairement au freinage "confort" (décélération à taux constant depuis
|
|
7
|
+
* la vitesse courante, qui peut prendre jusqu'à near un tour complet si la
|
|
8
|
+
* distance restante est grande), celui-ci respecte toujours le budget de
|
|
9
|
+
* temps demandé, quitte à accélérer au-delà de la vitesse de croisière.
|
|
10
|
+
*
|
|
11
|
+
* Utilisé identiquement par AnimationsMngr (spin, en degrés) et
|
|
12
|
+
* ChildrenOrbitManager (orbite, en radians) — les unités n'ont pas
|
|
13
|
+
* d'importance ici tant que `v0Mag`, `distance` et `targetDurationMs` sont
|
|
14
|
+
* exprimés de façon cohérente entre eux (deg/ms + deg, ou rad/ms + rad).
|
|
15
|
+
*
|
|
16
|
+
* Deux formes possibles :
|
|
17
|
+
* - "decel" : la décélération constante "naturelle" (celle qui ramènerait à
|
|
18
|
+
* vitesse nulle exactement à la distance `distance`) prend déjà moins de
|
|
19
|
+
* temps que `targetDurationMs` — on l'utilise telle quelle, ce qui termine
|
|
20
|
+
* AVANT l'échéance plutôt que d'artificiellement étirer l'arrêt.
|
|
21
|
+
* - "triangle" : cette décélération naturelle prendrait plus de temps que le
|
|
22
|
+
* budget imposé — on accélère d'abord jusqu'à une vitesse de pointe `vp`
|
|
23
|
+
* (calculée pour que la distance totale tombe pile juste), puis on
|
|
24
|
+
* décélère jusqu'à 0, les deux phases se partageant exactement
|
|
25
|
+
* `targetDurationMs` avec la même magnitude d'accélération. Cette
|
|
26
|
+
* contrainte (vitesse toujours ≥ vitesse de départ ou ≥ 0) garantit que la
|
|
27
|
+
* vitesse ne redevient jamais négative en cours de route — un simple
|
|
28
|
+
* polynôme cubique satisfaisant les 4 contraintes aux bords (position et
|
|
29
|
+
* vitesse de départ/arrivée) peut sinon, dans certains cas, brièvement
|
|
30
|
+
* repartir en arrière avant de revenir pile sur la cible.
|
|
31
|
+
*/
|
|
32
|
+
export type FastStopProfile = {
|
|
33
|
+
kind: "decel";
|
|
34
|
+
v0Mag: number;
|
|
35
|
+
accel: number;
|
|
36
|
+
durationMs: number;
|
|
37
|
+
} | {
|
|
38
|
+
kind: "triangle";
|
|
39
|
+
v0Mag: number;
|
|
40
|
+
/** Vitesse de pointe atteinte en fin de phase d'accélération. */
|
|
41
|
+
vp: number;
|
|
42
|
+
/** Durée de la phase d'accélération (0 à vp). */
|
|
43
|
+
t1: number;
|
|
44
|
+
/** Accélération de la phase 1 (peut être ~0 si t1 ~ 0). */
|
|
45
|
+
a1: number;
|
|
46
|
+
/** Décélération (magnitude) de la phase 2 (vp → 0). */
|
|
47
|
+
a2: number;
|
|
48
|
+
/** Distance déjà parcourue à la fin de la phase 1 — sert de base à la
|
|
49
|
+
* phase 2 (voir evaluateFastStopProfile). */
|
|
50
|
+
distPhase1: number;
|
|
51
|
+
durationMs: number;
|
|
52
|
+
};
|
|
53
|
+
export declare function computeFastStopProfile(v0Mag: number, distance: number, targetDurationMs: number): FastStopProfile;
|
|
54
|
+
export declare function evaluateFastStopProfile(profile: FastStopProfile, elapsedMs: number): {
|
|
55
|
+
speedMag: number;
|
|
56
|
+
distanceTraveled: number;
|
|
57
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/api-film.d.ts
CHANGED
|
@@ -21,6 +21,13 @@ export interface YinYangFilmConfig {
|
|
|
21
21
|
* clic sur la facette). Défaut : true. `false` = bordure neutre unique,
|
|
22
22
|
* sans calque de bordure par composante (film plus léger). */
|
|
23
23
|
highlightActiveSegment?: boolean;
|
|
24
|
+
/** Rend l'image figée du statut Idle (aucune facette active, illustration
|
|
25
|
+
* neutre — Homme de Vitruve — à la place du yin/yang, anneau de bordure
|
|
26
|
+
* non survolé, aucune étincelle) au lieu du film animé habituel. Mêmes
|
|
27
|
+
* calques que YinYangDrawer.refreshIdleSphereOverlay, capturés une seule
|
|
28
|
+
* fois : ni <style>, ni keyframes, ni étincelle — coût runtime nul, pour
|
|
29
|
+
* les marqueurs de carte qui n'ont pas besoin d'animation. Défaut : false. */
|
|
30
|
+
idle?: boolean;
|
|
24
31
|
}
|
|
25
32
|
/** Cuit un tour complet et renvoie un <svg> autonome (keyframes inlinées). */
|
|
26
33
|
export declare function createYinYangFilmSvg(config: YinYangFilmConfig): SVGSVGElement;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Cause } from "./interfaces/ICauseModel";
|
|
2
|
+
/** Intervalle inclusif [min, max]. */
|
|
3
|
+
export type RandomRange = [min: number, max: number];
|
|
4
|
+
export interface RandomCauseOptions {
|
|
5
|
+
/** Identifiant de la Cause produite (ex. id de la mission). Défaut : dérivé
|
|
6
|
+
* de la graine, sinon "random-<n>". */
|
|
7
|
+
id?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
/** Graine : même graine ⇒ même Cause. Sans graine, tirage Math.random. */
|
|
10
|
+
seed?: string | number;
|
|
11
|
+
/** Nombre de composantes (arcs de facette). Défaut : [2, 7]. */
|
|
12
|
+
components?: RandomRange;
|
|
13
|
+
/** ODD par composante, tirés sans remise parmi les 17 (jamais deux fois le
|
|
14
|
+
* même ODD dans une Cause, donc jamais deux fois la même couleur).
|
|
15
|
+
* Défaut : [1, 3] — plafonné par les ODD restants. */
|
|
16
|
+
oddsPerComponent?: RandomRange;
|
|
17
|
+
/** Facettes (satellites) par ODD. Défaut : [1, 4]. */
|
|
18
|
+
cuttingsPerOdd?: RandomRange;
|
|
19
|
+
/** Score de chaque facette. Défaut : [0.15, 0.85]. */
|
|
20
|
+
score?: RandomRange;
|
|
21
|
+
/** Poids entier de chaque facette. Défaut : [1, 3]. */
|
|
22
|
+
weight?: RandomRange;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Construit une `Cause` aléatoire : 2 à 7 composantes (orientations yin/yang
|
|
26
|
+
* alternées), chacune avec des ODD distincts tirés parmi les 17 — la couleur
|
|
27
|
+
* de chaque arc est donc celle de l'ODD officiel — et un nombre aléatoire de
|
|
28
|
+
* facettes par ODD (scores et poids aléatoires).
|
|
29
|
+
*
|
|
30
|
+
* À passer telle quelle à `createYinYangFilmSvg`, `mountYinYang`, etc.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createRandomCause(options?: RandomCauseOptions): Cause;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/api.d.ts
CHANGED
|
@@ -46,3 +46,6 @@ export declare function createYinYangSvg(config: YinYangSvgConfig): SVGSVGElemen
|
|
|
46
46
|
export declare function createYinYangSvgs(configs: YinYangSvgConfig[]): (SVGSVGElement | null)[];
|
|
47
47
|
export { createYinYangFilmSvg, createYinYangFilmSvgAsync } from "./api-film";
|
|
48
48
|
export type { YinYangFilmConfig, YinYangFilmAsyncOptions } from "./api-film";
|
|
49
|
+
export { createRandomCause } from "./api-random";
|
|
50
|
+
export type { RandomCauseOptions, RandomRange } from "./api-random";
|
|
51
|
+
export { getYasuniCause } from "./adapters/yasuniCauseAdapter";
|
|
@@ -96,6 +96,11 @@ export declare class YinYangController implements IYinYangController {
|
|
|
96
96
|
factory: IYinYangAppFactory;
|
|
97
97
|
animator: IAnimator;
|
|
98
98
|
private childControllers;
|
|
99
|
+
/** État de la rotation spin (voir startRotation/stopRotationAll) — non nul
|
|
100
|
+
* tant que la rotation est active, pour que les enfants recréés en cours
|
|
101
|
+
* de route (createYinYangChildren) démarrent immédiatement avec les mêmes
|
|
102
|
+
* réglages plutôt que de rester immobiles jusqu'à un prochain toggle. */
|
|
103
|
+
private rotationState;
|
|
99
104
|
private childrenOrbitManager;
|
|
100
105
|
private childOddMap;
|
|
101
106
|
/**
|
|
@@ -380,7 +385,11 @@ export declare class YinYangController implements IYinYangController {
|
|
|
380
385
|
private clearActiveChild;
|
|
381
386
|
private animateChildren;
|
|
382
387
|
private clearChildren;
|
|
383
|
-
setChildrenOrbitEnabled(isEnabled: boolean): void;
|
|
388
|
+
setChildrenOrbitEnabled(isEnabled: boolean, rampMs?: number): void;
|
|
389
|
+
/** Arrête l'orbite des satellites en rejoignant leur position de base dans
|
|
390
|
+
* une durée fixe `durationMs` (troisième mode d'arrêt — voir
|
|
391
|
+
* ChildrenOrbitManager.stopFast). */
|
|
392
|
+
stopChildrenOrbitFast(durationMs: number): void;
|
|
384
393
|
setChildrenOrbitDuration(_durationMs: number): void;
|
|
385
394
|
setChildrenOrbitSpeed(speed: number): void;
|
|
386
395
|
setChildrenOrbitRadiusScale(scale: number): void;
|
|
@@ -946,6 +955,20 @@ export declare class YinYangController implements IYinYangController {
|
|
|
946
955
|
* Rotations are reverted on click events.
|
|
947
956
|
*/
|
|
948
957
|
InitializeAnimations(): void;
|
|
958
|
+
/**
|
|
959
|
+
* Démarre la rotation spin de manière centralisée : ce composant ET tous
|
|
960
|
+
* ses satellites actuellement déployés. L'état est mémorisé pour que les
|
|
961
|
+
* satellites recréés ensuite (createYinYangChildren, ex. changement de
|
|
962
|
+
* facette) démarrent aussitôt avec les mêmes réglages plutôt que de rester
|
|
963
|
+
* immobiles jusqu'au prochain toggle.
|
|
964
|
+
*/
|
|
965
|
+
startRotation(clockWise: boolean, durationMs: number, rampMs?: number): void;
|
|
966
|
+
/** Arrête la rotation de ce composant ET de tous ses satellites actuels. */
|
|
967
|
+
stopRotationAll(rampMs?: number): void;
|
|
968
|
+
/** Arrête la rotation de ce composant ET de tous ses satellites en
|
|
969
|
+
* rejoignant leur position de base dans une durée fixe `durationMs`
|
|
970
|
+
* (troisième mode d'arrêt — voir AnimationsMngr.stopRotationFast). */
|
|
971
|
+
stopRotationAllFast(durationMs: number): void;
|
|
949
972
|
highlightOddInChildren(oddId: string | null): void;
|
|
950
973
|
highlightOddByStackItemId(stackItemId: string | null): void;
|
|
951
974
|
/**
|
|
@@ -12,14 +12,62 @@ export declare class ChildrenOrbitManager {
|
|
|
12
12
|
private deps;
|
|
13
13
|
private readonly orbitService;
|
|
14
14
|
private cachedOrbitData;
|
|
15
|
+
/** Temps de rampe (ms) courant pour l'accélération/décélération de la
|
|
16
|
+
* boucle active — mémorisé pour que setSpeed() (vitesse changée en vol)
|
|
17
|
+
* et la boucle elle-même s'y réfèrent sans avoir à le repasser partout. */
|
|
18
|
+
private rampMs;
|
|
19
|
+
/** Vitesse angulaire instantanée (rad/ms, signée) — chasse la vitesse
|
|
20
|
+
* cible (state.children.orbitSpeed, en rad/s) au rythme imposé par
|
|
21
|
+
* rampMs. */
|
|
22
|
+
private currentOmega;
|
|
23
|
+
private lastTimestamp;
|
|
24
|
+
/** Présent tant qu'un arrêt "retour à la position de base" est en cours :
|
|
25
|
+
* l'orbite continue sa course pour s'arrêter exactement sur un multiple
|
|
26
|
+
* de 2π (donc visuellement sur la position de base), plutôt que de couper
|
|
27
|
+
* la vitesse puis sauter à angle 0. Même principe que AnimationsMngr :
|
|
28
|
+
* `beginHomingStop` (mode "normal") décélère à taux constant, avec un tour
|
|
29
|
+
* de plus si besoin de confort ; `beginFastHomingStop` (mode "Accéléré")
|
|
30
|
+
* rejoint TOUJOURS le prochain passage par la position de base dans une
|
|
31
|
+
* durée fixe choisie par l'utilisateur — voir `fastHomingStop.ts`. */
|
|
32
|
+
private homeBrake?;
|
|
15
33
|
constructor(deps: ChildrenOrbitManagerDeps);
|
|
16
34
|
invalidateCache(): void;
|
|
17
35
|
buildOrbitData(): ChildrenOrbitEntry[];
|
|
18
36
|
applyTransforms(angleOffset: number, orbitData?: ChildrenOrbitEntry[]): void;
|
|
19
|
-
setEnabled(isEnabled: boolean): void;
|
|
37
|
+
setEnabled(isEnabled: boolean, rampMs?: number): void;
|
|
38
|
+
/** Change la vitesse cible. Si une boucle est déjà active, elle relit
|
|
39
|
+
* orbitSpeed à chaque frame et y converge au rythme de sa rampe en cours
|
|
40
|
+
* (pas besoin de la redémarrer) — un changement de vitesse en vol est
|
|
41
|
+
* donc lui aussi progressif plutôt que d'un coup. */
|
|
20
42
|
setSpeed(speed: number): void;
|
|
21
43
|
setRadiusScale(scale: number): void;
|
|
22
|
-
|
|
23
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Démarre (ou modifie en vol) l'orbite. Avec `rampMs > 0`, la vitesse
|
|
46
|
+
* angulaire part de sa valeur courante (0 si à l'arrêt) et chasse
|
|
47
|
+
* progressivement `state.children.orbitSpeed` (relu à chaque frame — un
|
|
48
|
+
* arrêt en cours de freinage repris ici ré-accélère en douceur depuis la
|
|
49
|
+
* vitesse déjà atteinte). `rampMs` omis (0) → vitesse cible appliquée
|
|
50
|
+
* instantanément, comportement historique.
|
|
51
|
+
*/
|
|
52
|
+
start(_targetSpeed: number, rampMs?: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Arrête l'orbite. Avec `rampMs > 0` et une orbite en cours, les satellites
|
|
55
|
+
* continuent leur course et décélèrent à taux constant pour s'arrêter
|
|
56
|
+
* exactement sur leur position de base (angle multiple de 2π) — voir
|
|
57
|
+
* `beginHomingStop`. `rampMs` omis (0) ou aucune orbite active → arrêt
|
|
58
|
+
* immédiat, comportement historique.
|
|
59
|
+
*/
|
|
60
|
+
stop(rampMs?: number): void;
|
|
61
|
+
/**
|
|
62
|
+
* Arrête l'orbite en rejoignant la position de base dans une durée FIXE
|
|
63
|
+
* `durationMs`, quelle que soit la distance restante (jamais de tour
|
|
64
|
+
* supplémentaire) — voir AnimationsMngr.stopRotationFast pour le même
|
|
65
|
+
* mécanisme côté rotation spin.
|
|
66
|
+
*/
|
|
67
|
+
stopFast(durationMs: number): void;
|
|
68
|
+
private computeRemainingToZero;
|
|
69
|
+
private beginHomingStop;
|
|
70
|
+
private beginFastHomingStop;
|
|
71
|
+
private finalizeStop;
|
|
24
72
|
}
|
|
25
73
|
export {};
|
|
@@ -104,6 +104,23 @@ export declare class YinYangDrawer {
|
|
|
104
104
|
private startOuterSparkAnimation;
|
|
105
105
|
private clearOuterSpark;
|
|
106
106
|
private normalizeAngle;
|
|
107
|
+
/**
|
|
108
|
+
* Peuple `filterEl` (un <filter> déjà créé, vide) avec un halo en deux
|
|
109
|
+
* couches derrière une copie nette de la source — pas juste un simple
|
|
110
|
+
* feGaussianBlur, qui ne fait qu'adoucir/affaiblir le trait lui-même sans
|
|
111
|
+
* rien ajouter autour : un flou seul redistribue l'énergie d'un trait fin
|
|
112
|
+
* sur une zone plus large, ce qui l'assombrit au lieu de "rayonner".
|
|
113
|
+
* Chaque couche est floutée puis son alpha est ré-amplifié (feColorMatrix,
|
|
114
|
+
* dernière ligne = multiplicateur d'alpha) pour qu'elle reste lumineuse
|
|
115
|
+
* malgré la dilution du flou, puis les deux couches sont fusionnées
|
|
116
|
+
* SOUS la source nette (feMerge, ordre = dessous → dessus).
|
|
117
|
+
*
|
|
118
|
+
* Les rayons de flou sont proportionnels à `scaleRadius` (le rayon du
|
|
119
|
+
* diagramme, pas une constante absolue en px) : un halo de quelques px ne
|
|
120
|
+
* se voit pas sur un grand diagramme mais engloutit tout sur un petit
|
|
121
|
+
* marqueur de carte — proportionnel, il reste visible dans les deux cas.
|
|
122
|
+
*/
|
|
123
|
+
private buildSparkGlowFilter;
|
|
107
124
|
private getOrCreateSparkLayer;
|
|
108
125
|
/**
|
|
109
126
|
* Triggers the "étincelle d'équilibre": two one-shot sparks running at
|
|
@@ -387,6 +404,22 @@ export declare class YinYangDrawer {
|
|
|
387
404
|
private isArcVisibleForLabel;
|
|
388
405
|
private renderOddArcLabels;
|
|
389
406
|
private applyOddArcLabelCounterRotation;
|
|
407
|
+
/**
|
|
408
|
+
* Contre-tourne le score et le poids affichés en permanence dans le noyau
|
|
409
|
+
* du lobe dominant — sur le cercle central (renderFacetteStateLabel/
|
|
410
|
+
* renderFacetteWeightLabel) comme sur un satellite (renderChildStateLabel/
|
|
411
|
+
* renderChildWeightLabel, un seul des deux paires existe selon isChild) —
|
|
412
|
+
* même principe que applyOddArcLabelCounterRotation, mais appliqué
|
|
413
|
+
* directement sur l'élément (pivot = sa propre position x/y) plutôt que
|
|
414
|
+
* via un groupe wrapper : contrairement aux labels d'arc ODD, ces montants
|
|
415
|
+
* sont déjà positionnés par des attributs x/y directs, donc une rotation
|
|
416
|
+
* autour de ce même point annule l'orientation héritée du spin du lobe
|
|
417
|
+
* sans déplacer le montant. Chaque satellite ayant son propre YinYangDrawer,
|
|
418
|
+
* cette méthode tourne indépendamment pour chacun (voir AnimationsMngr, qui
|
|
419
|
+
* l'appelle via component.view.yinYangDrawer pour le composant en train de
|
|
420
|
+
* tourner, parent ou enfant).
|
|
421
|
+
*/
|
|
422
|
+
private applyFacetteAmountLabelsCounterRotation;
|
|
390
423
|
private getRotationAngleFromTransform;
|
|
391
424
|
private getDisplayedArcAngles;
|
|
392
425
|
/**
|
|
@@ -2,6 +2,13 @@ export declare const animationConfig: {
|
|
|
2
2
|
componentSwitchDurationMs: number;
|
|
3
3
|
borderColorCycleDurationMs: number;
|
|
4
4
|
rotationDurationMs: number;
|
|
5
|
+
/** Temps de rampe (ms) par défaut pour l'accélération/décélération
|
|
6
|
+
* progressive de la rotation Yin/Yang (voir AnimationsMngr.animate /
|
|
7
|
+
* stopRotation) — 0 donnerait le comportement historique (à-coup). */
|
|
8
|
+
rotationRampMs: number;
|
|
9
|
+
/** Idem, pour l'orbite des satellites autour du cercle central (voir
|
|
10
|
+
* ChildrenOrbitManager.start / stop) — même rôle, mécanisme séparé. */
|
|
11
|
+
orbitRampMs: number;
|
|
5
12
|
forceFieldRevealDurationMs: number;
|
|
6
13
|
forceFieldRevealChainStepMs: number;
|
|
7
14
|
/** Fondu de sortie du champ de force d'action ET du champ d'événement quand
|
|
@@ -13,7 +13,10 @@ export interface IYinYangController {
|
|
|
13
13
|
clearForceFieldDetails(): void;
|
|
14
14
|
applyChildrenFitScale(): void;
|
|
15
15
|
setChildrenEnabled(isEnabled: boolean): void;
|
|
16
|
-
setChildrenOrbitEnabled(isEnabled: boolean): void;
|
|
16
|
+
setChildrenOrbitEnabled(isEnabled: boolean, rampMs?: number): void;
|
|
17
|
+
/** Arrête l'orbite des satellites en rejoignant leur position de base dans
|
|
18
|
+
* une durée fixe (troisième mode d'arrêt). */
|
|
19
|
+
stopChildrenOrbitFast(durationMs: number): void;
|
|
17
20
|
setChildrenOrbitDuration(durationMs: number): void;
|
|
18
21
|
setChildrenOrbitSpeed(speed: number): void;
|
|
19
22
|
setChildrenOrbitRadiusScale(scale: number): void;
|
|
@@ -35,6 +38,15 @@ export interface IYinYangController {
|
|
|
35
38
|
getParentKey(): string | null;
|
|
36
39
|
generateChildKey(): string;
|
|
37
40
|
InitializeAnimations(): void;
|
|
41
|
+
/** Démarre la rotation spin de ce composant ET de tous ses satellites
|
|
42
|
+
* actuellement déployés — voir AnimationsMngr.animate pour la sémantique
|
|
43
|
+
* de rampMs. */
|
|
44
|
+
startRotation(clockWise: boolean, durationMs: number, rampMs?: number): void;
|
|
45
|
+
/** Arrête la rotation spin de ce composant ET de tous ses satellites. */
|
|
46
|
+
stopRotationAll(rampMs?: number): void;
|
|
47
|
+
/** Arrête la rotation spin en rejoignant la position de base dans une
|
|
48
|
+
* durée fixe (troisième mode d'arrêt). */
|
|
49
|
+
stopRotationAllFast(durationMs: number): void;
|
|
38
50
|
highlightOddInChildren(oddId: string | null): void;
|
|
39
51
|
refreshWeightPreviewPulse(): void;
|
|
40
52
|
enterOddView(oddId: string): void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Suivi partagé de l'inactivité utilisateur (aucune interaction — souris,
|
|
3
|
+
* clavier, tactile — sur le document) : un seul jeu d'écouteurs global,
|
|
4
|
+
* plusieurs "watchers" indépendants peuvent s'y abonner avec leur propre
|
|
5
|
+
* délai (relu en direct, donc réglable via un slider sans se réabonner) et
|
|
6
|
+
* reçoivent onIdle() une fois ce délai écoulé sans activité, puis onActive()
|
|
7
|
+
* dès que l'activité reprend — jusqu'au prochain cycle idle → actif.
|
|
8
|
+
*/
|
|
9
|
+
declare class InactivityTracker {
|
|
10
|
+
private lastActivityAt;
|
|
11
|
+
private watchers;
|
|
12
|
+
private intervalId;
|
|
13
|
+
private readonly handleActivity;
|
|
14
|
+
/** S'abonne au suivi d'inactivité. `getThresholdMs` est relu à chaque
|
|
15
|
+
* vérification (pas figé à l'abonnement), pour suivre un slider réglé en
|
|
16
|
+
* direct. Retourne une fonction de désabonnement. */
|
|
17
|
+
register(getThresholdMs: () => number, onIdle: () => void, onActive: () => void): () => void;
|
|
18
|
+
private ensureListening;
|
|
19
|
+
private teardown;
|
|
20
|
+
private tick;
|
|
21
|
+
}
|
|
22
|
+
/** Instance unique partagée par tous les contrôles qui déclenchent un
|
|
23
|
+
* comportement automatique après inactivité (voir VizControlsPanel). */
|
|
24
|
+
export declare const inactivityTracker: InactivityTracker;
|
|
25
|
+
export {};
|
package/package.json
CHANGED