Types d'actions
Les types d'actions suivants sont disponibles. Tous partagent un jeu de champs
communs (cycle de vie : id, duration,
wait_for, keep_until, keep_until_next, keep_until_end).
move
Déplace un objet dynamique de from vers to.
{
type: 'move',
object: 'req', // id d'un packet
from: 'browser', // id d'un node
to: 'api', // id d'un node
duration: 600,
}
Produit deux points d'arrêt : apparition et arrivée. Par défaut, l'objet disparaît à la fin de son animation.
arrow
Trace une flèche animée entre deux nœuds (dessin progressif).
{
type: 'arrow',
from: 'a',
to: 'b',
style: 'dashed', // 'solid' | 'dotted' | 'dashed' | 'animated'
path: 'bezier', // 'bezier' | 'simplebezier' | 'straight' | 'step' | 'smoothstep'
arrow_head: 'both', // 'forward' | 'backward' | 'both' | 'none'
text: 'requête',
}
Pour des flèches permanentes (décor affiché dès l'initialisation),
utilisez plutôt le tableau racine connections.
parallel
Encapsule des actions enfants exécutées au même instant.
{
type: 'parallel',
actions: [
{ type: 'move', object: 'p1', from: 'a', to: 'b' },
{ type: 'arrow', from: 'c', to: 'd' },
],
}
Les wait_for et keep_until à l'intérieur d'un parallel continuent de
fonctionner normalement. Ici, un move et un arrow de types différents
démarrent au même instant.
loading
Affiche un spinner de chargement sur un nœud cible (simule un traitement).
{ type: 'loading', object: 'db', duration: 900 }
set_content
Mute le contenu d'un nœud. Le contenu suit la forme ObjectContent, partagée
avec le champ content d'un
nœud. Cinq modes via type :
code: terminal sombre avec coloration Prism, sans barre d'URL ; la police s'ajuste pour faire tenir la ligne la plus longue sans wrap.text: fenêtre de navigateur avec barre d'URL paramétrable (url).image: image (value= chemin/URL) affichée dans une fenêtre, ou séquence animée (frames).table: tableau de données (columns+rows_data).html: balisage riche, assaini (value).
valueLe champ porte-contenu s'appelle value (pas content). Le content est
l'objet englobant.
Mode code :
{
type: 'set_content',
object: 'editor',
content: {
type: 'code',
language: 'javascript',
value: 'const add = (a, b) => a + b;',
},
}
Mode text (fenêtre de navigateur avec barre d'adresse) :
{
type: 'set_content',
object: 'browser',
content: {
type: 'text',
url: 'exemple.com/users',
value: 'Alice\nBob',
},
}
Mode table :
{
type: 'set_content',
object: 'admin',
content: {
type: 'table',
columns: ['id', 'nom'],
rows_data: [
[1, 'Alice'],
[2, 'Bob'],
],
},
}
| Champ | Modes concernés | Rôle |
|---|---|---|
type | tous | code | text | image | table | html. |
value | code/text/image/html | Texte source, chemin d'image, ou balisage. |
language | code | Langage de coloration (cf. HighlightLanguage). |
url | text/html | Barre d'adresse de la fenêtre. |
columns | table | En-têtes de colonnes. |
rows_data | table | Lignes de données. |
screen_width | html | Largeur de conception en px — fait du panneau un écran. |
screen_height | html | Hauteur de conception en px (défaut screen_width × 0,625). |
frames | image | Séquence d'images, jouée sur l'horloge de l'animation. |
fps | image | Cadence de frames (12 par défaut, bornée 0,1–60). |
loop | image | false retient la dernière image au lieu de reboucler. |
Les trois modes textuels, côte à côte (code, text, puis table) :
html — balisage riche
Le balisage de value est analysé inerte, puis reconstruit depuis une
liste blanche : mise en forme, listes, tableaux, img, et un sous-ensemble
étroit de SVG inline. Une spec est une donnée — elle peut venir d'un CMS ou d'un
formulaire — donc tout ce qui n'est pas sur la liste est écarté silencieusement :
<script>, <style>, <iframe>, tous les gestionnaires on*, et toute URL
dont le schéma n'est ni http, ni https, ni data:image/….
classclass et id sont écartés, et ce n'est pas une décision de sécurité. Une image
vidéo rasterisée n'embarque que les règles CSS dont le sélecteur contient rdfa
: une classe stylée par la page hôte s'afficherait à l'écran et sans style dans
la vidéo exportée — la même spec, deux images différentes. Le style inline,
lui, voyage avec l'élément : c'est celui qu'il faut utiliser. Il est filtré aussi
: position et les propriétés personnalisées sont refusées (elles laisseraient
le contenu sortir de son nœud ou repeindre le lecteur), et url(…) est refusé
dans toute valeur.
{
type: 'set_content',
object: 'card',
content: {
type: 'html',
value:
'<h3>Cache préchauffé</h3>' +
'<ul><li><b>Taux de succès</b> 94 %</li></ul>' +
'<p style="color:#16a34a">Tous les fragments au vert</p>',
},
}
Contrairement à text, un panneau html n'affiche le chrome de navigateur que
si vous lui donnez une url — un balisage riche est aussi souvent une légende
ou une fiche qu'une page web.
screen_width — une page qui se met à l'échelle au lieu de se remettre en page
Par défaut, un panneau riche se comporte comme un paragraphe : sa boîte est plafonnée par l'allocation du nœud et sa typographie garde la taille que lui donne la feuille de style — le même balisage devient donc une mise en page à deux colonnes sur un grand lecteur et une pile de lignes repliées sur un petit. Pour une interface simulée, c'est le mauvais comportement : la disposition EST le message, et un étudiant doit reconnaître le même écran à toutes les tailles.
Renseignez screen_width et le panneau devient un écran : le balisage est
mis en page une seule fois, dans cet espace de pixels, et le rendu ne change plus
que l'ÉCHELLE.
content: {
type: 'html',
url: 'videos.example/watch?v=42',
screen_width: 480, // l'espace de conception contre lequel on écrit
screen_height: 300, // facultatif — par défaut 480 × 0,625, un écran 16:10
value: '<div style="display:flex">…</div>',
}
Trois conséquences à connaître :
- La barre d'adresse passe à l'intérieur de l'écran, donc elle se met à l'échelle avec la page au lieu de rester à côté à la taille du lecteur — un navigateur simulé est une seule image.
- La mise à l'échelle du lecteur s'arrête au bord de l'écran. À l'intérieur,
12pxvaut 12 pixels de conception, quelle que soit la taille de la fenêtre. - Un écran est une boîte fixe : ce qui ne rentre pas est rogné, exactement comme un vrai écran rogne ce qui est sous la ligne de flottaison.
Ci-dessous : une page dont la coquille ne bouge pas pendant que ses données
arrivent. Les deux set_content portent fade_in_ms: 0, donc le basculement est
instantané — et comme le balisage de la coquille est identique de part et
d'autre, seule la région qui a changé semble changer. C'est ce qui le fait lire
comme une application monopage plutôt que comme un rechargement.
image — une image fixe, ou une séquence animée
value seul donne une image fixe. frames est une liste ordonnée de sources
d'images jouée sur l'horloge de l'animation : l'image à l'écran est une
fonction pure de t, exactement comme toute autre valeur rendue.
{
type: 'set_content',
object: 'worker',
content: {
type: 'image',
frames: ['data:image/svg+xml,…', 'data:image/svg+xml,…'],
fps: 8,
},
}
C'est ce qu'un GIF animé ne sait pas faire. La tête de lecture d'un GIF est
inaccessible depuis JavaScript : il continue de tourner pendant que le lecteur
est en pause, ne rembobine pas quand on scrube en arrière, et une image exportée
attrape l'instant où le décodeur se trouvait. Une séquence frames se met en
pause, rembobine et s'exporte image par image.
Un set_content sans duration explicite reçoit le temps nécessaire à sa
séquence pour se dérouler une fois, au lieu du battement fixe d'une image.
data:Une image vidéo rasterisée ne peut rien charger depuis une autre origine. Une
entrée de frames (ou un <img src> dans un panneau html) qui pointe vers une
URL distante s'affiche à l'écran et fait échouer l'export vidéo.
comment
Affiche une bulle de texte en fondu près d'un nœud, identifié par object.
{
type: 'comment',
object: 'browser',
text: 'L\'utilisateur clique',
duration: 400,
}
Commentaire omniscient : omettez object pour afficher la bulle en haut
de la scène plutôt qu'à côté d'un nœud — idéal pour une narration générale qui
ne se rattache à aucun composant précis.
{ type: 'comment', text: 'Étape 2 — Authentification' }
Ci-dessous, un commentaire omniscient (en haut de la scène) suivi de deux bulles attachées à des nœuds :
set_visible
Affiche ou cache un nœud statique avec un fondu. Le nœud cible peut démarrer
caché (visible: false dans sa déclaration) puis être révélé, ou inversement.
L'état de visibilité persiste jusqu'à la fin de la chronologie (ou jusqu'à
un set_visible contraire).
{ type: 'set_visible', object: 'cache', visible: true }
Voir Nœuds → visible
pour l'usage combiné avec la visibilité initiale.
set_color
Recolore un nœud statique à l'exécution. Mute n'importe lequel des trois canaux
de couleur — background_color, border_color, text_color — sur duration
ms, avec un fondu enchaîné eased et déterministe entre l'ancienne couleur
et la nouvelle (via color-mix CSS, donc scrubbable dans les deux sens). Seuls
les canaux que vous fournissez changent ; les autres gardent leur valeur
courante.
{ type: 'set_color', object: 'noeud', background_color: '#1f2937', duration: 600 }
Même espace de valeurs que les couleurs de nœud :
un nom CSS prédéfini (tomato, steelblue…) ou un hexadécimal exact
(#1a1a1a). Les mêmes dérivations automatiques s'appliquent — un
background_color sans border_color dérive une bordure coordonnée, et sans
text_color une encre à fort contraste (hors zones de coloration syntaxique).
La couleur atteinte persiste jusqu'à la fin de la chronologie (comme
set_visible), et des set_color successifs sur le même nœud s'enchaînent :
chacun part en fondu de la couleur précédente.
C'est l'opération centrale des visualisations d'algorithmes qui recolorent des nœuds — par exemple la recoloration rouge/noir d'un arbre rouge-noir. Ci-dessous, un nœud inséré « rouge » est recoloré en « noir » :
set_color recolore aussi une connexion permanente :
passez l'id de la connexion comme object et un unique color (les trois
canaux de nœud ne s'appliquent pas à un trait). Le trait et sa pointe passent en
fondu depuis leur couleur courante — idéal pour allumer l'arête qu'un parcours de
graphe vient d'emprunter :
{ type: 'set_color', object: 'edge', color: 'seagreen', duration: 500 }
set_icon
Met à jour le badge d'icône d'angle d'un nœud à l'exécution — le petit badge
superposé (icon : une techno connue, une icône enregistrée, ou un court texte
libre). Le badge bascule sur la nouvelle valeur au démarrage de l'action ; la
valeur atteinte persiste jusqu'à la fin de la chronologie (comme
set_color), et les set_icon successifs sur le même nœud s'enchaînent. Une
chaîne vide efface le badge.
{ type: 'set_icon', object: 'v', icon: '7' }
C'est ainsi qu'une visualisation d'algorithme garde lisible, sur le nœud
lui-même, un scalaire par nœud qui évolue — la distance provisoire d'un nœud
Dijkstra (∞ → 7 → 5), le f = g + h d'un nœud A* — plutôt que seulement dans un
commentaire. Ci-dessous, le badge d'un nœud descend de ∞ jusqu'à sa valeur
finale :
rotate
Anime la rotation du visuel d'un nœud. Deux modes mutuellement exclusifs ; seul le visuel pivote (le label en dessous reste droit), et l'angle atteint à la fin de la rotation persiste jusqu'à la fin de la chronologie.
Angle cible to (en degrés, sens horaire) : une rotation unique avec
inertie (eased). L'angle de départ est la rotation courante du nœud — son champ
statique rotation, ou la
cible d'un rotate précédent — si bien que les rotations successives
s'enchaînent.
{ type: 'rotate', object: 'gear', to: 90, duration: 600 }
Un tour complet s'écrit simplement to: 360 (depuis 0) ; on revient avec
to: 0.
Rotation continue spin (en degrés par seconde, signé — positif = sens
horaire, négatif = sens anti-horaire) : le nœud tourne à vitesse constante
(linéaire, sans inertie). Sa durée réutilise les champs de
timing habituels — duration, keep_until ou
keep_until_end — au lieu d'un angle cible.
{ type: 'rotate', object: 'gear', spin: 360, keep_until_end: true } // jusqu'à la fin
{ type: 'rotate', object: 'gear', spin: -180, duration: 3000 } // 3 s, anti-horaire
{ type: 'rotate', object: 'gear', spin: 90, keep_until: 'response' } // jusqu'à l'action « response »
Si to et spin sont fournis ensemble, spin l'emporte.
rotate_subtree
Restructure un arbre binaire par une rotation d'arbre autour d'un pivot, puis
anime les nœuds qui glissent à leur nouvelle place pendant que les arêtes
parent/enfant se re-câblent. Valide uniquement en
direction: 'tree', qui fournit le bloc
tree que cette action mute.
{ type: 'rotate_subtree', object: '10', rotation: 'left' } // ou 'right'
Une rotation gauche fait monter l'enfant droit du pivot ; une rotation droite fait monter son enfant gauche (l'enfant requis doit exister, sinon un avertissement est émis et rien ne bouge). Une rotation préserve le parcours in-order de l'arbre : les positions horizontales ne changent pas — le mouvement est le changement de profondeur du pivot et du sous-arbre déplacé.
Des rotate_subtree successifs s'enchaînent (chacun part de la topologie
laissée par le précédent) : c'est ainsi qu'on exprime les rotations doubles
AVL — un cas LR est une rotation gauche sur l'enfant suivie d'une rotation
droite sur le grand-parent. Ci-dessous, une seule rotation gauche rééquilibre une
chaîne penchée à droite :
highlight
Surligne (halo pulsé) un nœud statique ou une connexion permanente,
identifiés par leur id.
{ type: 'highlight', object: 'db' }
Ici, le halo pulse d'abord sur le nœud db, puis sur la connexion
permanente link :
Pour mettre en avant une connexion dès le départ (sans action de timeline),
utilisez plutôt son champ statique
highlighted.
flow
Anime un courant électrique qui circule le long d'une chaîne de fils — c'est
l'animation phare d'un schéma électrique.
Un train de charges régulièrement espacées parcourt le route (une liste
ordonnée de références node / node:pin formant un parcours ou une boucle
fermée), avançant d'un tour complet par duration ms et, par défaut, en boucle
continue. Chaque paire consécutive du parcours doit être reliée par un vrai fil
(connection), pour que les charges suivent exactement le tracé.
{
type: 'flow',
route: ['battery:+', 'R1:a', 'R1:b', 'led:a', 'led:b', 'battery:-'],
color: '#f59e0b', // défaut : l'accent du thème
keep_until_end: true,
}
reverse: true envoie les charges dans l'autre sens (flux électronique − → + au
lieu du courant conventionnel + → −) ; loop: false joue un seul passage ;
count fixe le nombre de charges (défaut : environ une par segment). Étant une
fonction pure de t, le courant se scrube dans les deux sens comme le reste.
Voir la démo Circuit électrique de la galerie.
toggle
Bascule un switch / push_button électrique entre ouvert et fermé, en faisant
pivoter le levier sur duration ms. Comme set_visible, l'état
atteint persiste jusqu'à la fin de la chronologie (ou au prochain toggle
contraire) et se scrube dans les deux sens. Associez-le à un flow qui démarre
une fois le contact fermé pour montrer la mise sous tension du circuit.
{ type: 'toggle', object: 'sw', closed: true }
wait
Insère un temps mort : rien ne se passe pendant duration ms (défaut :
1000). L'action ne produit aucun élément à l'écran ; elle se contente de
décaler l'étape suivante. Le contenu déjà posé (via keep_until_next)
reste affiché pendant l'attente, ce qui fige l'image le temps voulu.
{ type: 'wait', duration: 1500 }
Utile pour laisser le spectateur lire une étape avant de poursuivre, ou
pour rythmer une lecture en autoPlay.
Référence complète
Pour la liste exhaustive des champs (types, valeurs par défaut, contraintes), voir la référence API générée à partir du JSON Schema.