Démonstration · construite pour ce site en 1 jour · non commanditée
Mettre en orbite
Une manipulation de borne : on lance un satellite depuis son altitude de départ, on observe l’orbite se dessiner, on comprend pourquoi ça retombe, ça tourne ou ça s’échappe. Trois missions guidées, aucune phrase de plus de douze mots, retour à l’accueil après 45 secondes sans interaction.
Touche le satellite et tire.
Distances à l’échelle · taille du satellite exagérée · sans atmosphère ni Lune
Flèches ← → : angle ± 2°. ↑ ↓ : vitesse ± 0,1 km/s (Maj : ± 1). Entrée : lancer. Espace : pause. Échap : recommencer.
Réglages exploitant
Ce que ça démontre
Un geste pour un public debout. Le visiteur pose le doigt sur le satellite, tire, relâche. La flèche part du satellite et indique où il ira : la direction et la vitesse tiennent dans un seul mouvement, sans mode d’emploi. Le retour est immédiat, les consignes font douze mots au plus, et chaque mission se termine par une phrase qu’on retient.
Une physique simplifiée mais exacte. Deux corps, Terre fixe, gravitation newtonienne. Dès le lancement, l’orbite est classée analytiquement à partir de la position et de la vitesse (énergie, moment cinétique, excentricité, périgée, apogée, période de Kepler) ; l’animation ne fait que la tracer, avec un intégrateur symplectique qui conserve l’énergie à mieux que 0,1 % sur une révolution. Les valeurs de référence (7,67 km/s et 92 min pour l’ISS, 11,2 km/s de libération, 35 786 km pour la géostationnaire) sont vérifiées par des tests automatisés.
La robustesse d’un mode kiosque. Retour automatique à l’accueil après quarante-cinq secondes sans interaction, désactivable par le visiteur et prolongeable sans limite ; deuxième pointeur ignoré pendant 300 ms (deux mains sur l’écran) ; boucle d’animation active uniquement pendant un vol visible ; mode borne en plein écran avec cibles agrandies ; réglages exploitant mémorisés sur la machine.
Comment c’est conçu
La question de départ n’était pas « comment simuler une orbite » mais « qu’est-ce qu’un enfant de dix ans doit comprendre en trente secondes ». Réponse : que la vitesse décide de tout. D’où un seul paramètre visible (la longueur de la flèche) et trois issues nommées : retombe, tourne, s’échappe.
- à venir
Croquis papier — à venir
- à venir
Maquette Figma — à venir
- à venir
Écran final — à venir
Ce que j’ai rejeté, et pourquoi
-
Un curseur de vitesse et un bouton « Lancer »
Debout devant une borne, on ne lit pas un curseur : on touche ce qu’on voit. Le geste « tirer le satellite » porte la direction et la vitesse dans un seul mouvement, sans mode d’emploi.
Gardé à la place — un seul geste, la flèche part du satellite et indique où il ira ; les boutons restent pour le clavier.
-
Une échelle de distances « arrangée » pour que tout tienne
Un médiateur de centre spatial le voit en une seconde, et la leçon (« à 35 786 km, un tour dure un jour ») devient fausse à l’écran.
Gardé à la place — distances à l’échelle, cadrage qui change selon la mission (3, 8, 16 ou 30 rayons terrestres), taille du satellite exagérée et dite.
-
Simuler l’atmosphère et la Lune
Plus juste, mais plus rien n’est lisible en trente secondes : la question de la borne est « pourquoi ça tombe, ça tourne ou ça s’échappe », pas la mécanique céleste complète.
Gardé à la place — deux corps, Terre fixe, mention permanente « sans atmosphère ni Lune ».
Comment c’est construit
Toute la logique tient dans un réducteur : un état, une action, un nouvel état. Le DOM n’est qu’une projection de cet état, ce qui rend les tests triviaux et le comportement prévisible pour un responsable technique qui reprend le code.
// src/scripts/orbit-demo.ts — l'unique fonction de transition.
// Chaque action produit un nouvel état, sans effet de bord ; le lancement
// classe l'orbite analytiquement (énergie, moment cinétique, excentricité),
// le vol ne sert qu'à tracer et s'arrête à la collision, à la libération
// ou après un tour complet.
export function transition(s: State, a: Action): State {
switch (a.type) {
case 'accueil':
return { kind: 'accueil' };
case 'reveiller':
return s.kind === 'accueil' ? { kind: 'visee', angle: 90, speed: a.speed } : s;
case 'viser':
if (s.kind === 'vol' || s.kind === 'pause') return s;
return { kind: 'visee', angle: ((a.angle % 360) + 360) % 360,
speed: Math.min(MAX_SPEED, Math.max(0, a.speed)) };
case 'lancer': {
if (s.kind !== 'visee' && s.kind !== 'resultat') return s;
const body = launch(a.altitudeKm, s.speed, s.angle);
return { kind: 'vol', angle: s.angle, speed: s.speed, body,
orbit: classify(body), trail: [body.x, body.y] };
}
case 'avancer': {
if (s.kind !== 'vol' || a.steps <= 0) return s;
const { body, event } = advance(s.body, a.dt, a.steps);
const trail = s.trail.length >= MAX_TRAIL_POINTS * 2 ? s.trail.slice(2) : s.trail.slice();
trail.push(body.x, body.y);
const done = event !== null || (s.orbit.kind === 'orbite' && body.t >= s.orbit.period);
return done ? { ...s, kind: 'resultat', body, trail, event } : { ...s, body, trail };
}
case 'pause':
return s.kind === 'vol' ? { ...s, kind: 'pause' } : s;
case 'reprendre':
return s.kind === 'pause' ? { ...s, kind: 'vol' } : s;
case 'recommencer':
return s.kind === 'accueil' ? s : { kind: 'visee', angle: s.angle, speed: s.speed };
}
}
// src/lib/orbit.ts — classification à partir de (r, v), sans intégrer.
export function classify(b: Body): Orbit {
const r = Math.hypot(b.x, b.y);
const energy = (b.vx * b.vx + b.vy * b.vy) / 2 - 1 / r; // ε = v²/2 − GM/r
const h = b.x * b.vy - b.y * b.vx; // moment cinétique
const e = Math.sqrt(Math.max(0, 1 + 2 * energy * h * h)); // excentricité
const bound = energy < 0;
const a = energy === 0 ? Infinity : -1 / (2 * energy); // demi-grand axe
const perigee = (h * h) / (1 + e);
const apogee = bound ? a * (1 + e) : Infinity;
const period = bound ? periodForSemiMajorAxis(a) : Infinity; // T = 2π √(a³/GM)
// …
} src/lib/orbit.ts— mécanique à deux corps, classification, intégrateur, préréglages, formats (≈ 2,5 ko compressé).src/lib/orbit-canvas.ts— rendu canvas 2D, cadrages, positions écran pour les étiquettes en DOM.src/scripts/orbit-demo.ts— machine à états, geste, clavier, missions, kiosque, réglages.tests/orbit.test.ts— valeurs de référence, conservation de l’énergie, transitions, geste, verdicts.scripts/posters/orbite.mjs— poster SVG statique généré au build avec le même moteur (repli sans JavaScript).
Accessibilité
- Clavier — le simulateur est focusable (rôle application) : flèches pour l’angle et la vitesse, Entrée pour lancer, Espace pour la pause, Échap pour recommencer. Les mêmes actions existent en boutons.
- Lecteur d’écran — pendant la visée, la vitesse, l’angle et la prédiction (« Orbite stable, période 92 minutes ») sont annoncés dans une zone polie unique, avec anti-rebond ; l’issue et la leçon le sont à la fin du vol.
- Mouvement réduit — pas de vol animé : la trajectoire complète est tracée d’un coup, l’issue est annoncée tout de suite, et un bouton « Étape suivante » permet de parcourir le vol par pas.
- Minuteries — le retour automatique est désactivable par la case sous la démo ; le bandeau « Toujours là ? » se prolonge sans limite.
- Sans JavaScript — le poster montre les trois trajectoires types ; la manipulation nécessite JavaScript.
- Reste à améliorer — tests avec lecteurs d’écran réels sur tablette (TalkBack, VoiceOver iOS) et validation des cibles de 64 px sur un écran de borne physique.
Pour votre lieu
Dans un centre spatial, cette manipulation devient une borne du parcours « lanceurs et satellites », avec vos vraies missions en préréglages et vos textes de médiateurs, testée avec des scolaires avant l’installation.
Ce concept vous parle ? Il reste à l’adapter à votre lieu, votre public et vos contraintes. Parler de votre projet →