En tant que passionné d’astronomie, j’ai tenté de réaliser il y a quelques mois une petite animation de notre très célèbre système solaire, grâce à du HTML et de la CSS seulement.
Le problème est qu’il est très difficile de le recréer à l’échelle, les distances entre les planètes sont extrêmement importantes par rapport à leurs tailles. Pour vous donner une idée, cette expérience de Josh Worth que je trouve absolument bien réalisée représente notre système solaire en partant du principe qu’un pixel représente notre Lune : If the Moon were only 1 pixel
La Lune, prise le 14 août 2014, peu après la « Super Lune » à travers mon télescope.
C’est pourquoi je me suis concentré essentiellement sur l’échelle temporelle.
Révolutions des planètes
Avant de commencer, un peu de documentation. On sait que les planètes ont un temps de révolution qui est différent en fonction de leur distance avec le soleil. Sur Wikipédia, on peut trouver ceci :
Révolution des planètes en jours terrestres
- Mercure : env. 87,5 jours
- Venus : env. 224,7 jours
- Terre : env. 365,2563 jours (et la Lune : env. 27,3216 jours autour de la terre, toujours bon de le rappeler aux philosophes des télés-réalité)
- Mars : env. 687 jours (env. 1,8 ans)
- Jupiter : env. 4 331 days (env. 12 ans)
- Saturne : env. 10 747 jours (env. 30 ans)
- Uranus : env. 30 589 jours (env. 84 ans)
- Neptune : env. 59 802 jours (env. 165 ans)
- Pluton : env. 90 580 jours (env. 248 ans)
Pluton tu es dans mon cœur, tu as toujours été une planète pour moi !
Imaginez un peu, en 1767 Pluton entamait une révolution autour du Soleil qu’elle vient de finir cette année.
Le code HTML
Pour représenter les planètes sur les orbites, c’est une question d’illusion. Je vais créer un div
vide. En ajoutant un grand border-radius
et un border
sur ce div
j’aurais un cercle : l’orbite. Pas besoin d’encombrer le dom pour les planètes, ce seront des pseudo-éléments div:before
ou div:after
selon votre préférence, avec les propriétés qui lui iront bien pour représenter un disque.
Les variables SCSS
Notre échelle de temps sera donc basée sur le temps terrestre.
En établissant la variable sass ci-dessous, je pourrai m’y référer plus tard dans le code.
La Terre sur la simulation tournera autour du Soleil en 30 sec (ce qui équivaut à un an).
Ainsi, si je décide d’accélérer ou au contraire réduire la vitesse de toutes les planètes en même temps, je changerais la valeur de cette variable.
J’aurais donc besoin de définir la taille des différents orbites *-orb
, et des planètes *-pl
.
La fonction
Ou devrais-je dire, la fonction clé de cette animation sera celle ci :
Un simple produit en croix pour avoir le temps en secondes pour l’animation de mes planètes.
Elle sert à traduire le nombre de jours propres à chaque planète en jours terrestres, pour enfin donner une valeur en seconde de l’animation (en fonction de la variable $year-in-second
).
Je n’ai pas mis la valeur des jours terrestres 365.2563
dans une variable, car c’est une valeur immuable.
Par exemple, pour Saturne je devrais écrire dans la propriété animation
:
Ce qui en ressort en CSS :
L’animation Keyframes
Pour faire tourner nos planètes on a besoin de définir une animation
Oui, j’ai bien mis -360deg
car les planètes tournent dans le sens inverse des aiguilles d’une montre (en supposant qu’on regarde du dessus).
Avec tout ça, on peut déjà commencer à s’amuser un peu. Voici un exemple via Codepen.
Je disais plus haut « une illusion », car en réalité c’est le div
de l’orbite qui tourne sur lui même et non pas le pseudo-élément.
Attention, ce pen utilise compass et autoprefixer. Si vous ne connaissez pas je vous conseille d’y jeter un œil !
Pour la Lune on a une petite spécificité car elle tourne autour de la Terre, qui elle même tourne autour du soleil.
Donc on va utiliser un autre pseudo-élément :after
, ce sera l’orbite de la Lune. Vous me suivez ?
« Oui mais, on ne peut pas faire de pseudo-élément de pseudo-élément ? Comment va-t-on créer la Lune ? » Non, on ne peut pas. En revanche avec un peu d’astuce on pourrait utiliser le box-shadow
de notre orbite pour faire la Lune.
J’ai volontairement mis d’autres tailles dans cet exemple pour mieux voir
En jouant avec la taille du bow-shadow
on peut jouer sur la distance et la grandeur de la Lune.
-19px
éloigne la Lune, et -7px
réduit sa taille car par défaut, l’ombre d’un élément sera égale à la taille de l’élément lui même. Ici notre élément fait 18px
, si j’avais laissé la valeur à 0
la Lune aurait été trop grosse.
Un fond étoilé
Je ne souhaitais pas utiliser d’image dans cette expérience, voici donc deux petites fonctions assez avancées qui permettent d’avoir un fond étoilé aléatoirement :
Celle-ci retourne une valeur aléatoire pour l’opacité de chaque étoile.
Celle-ci crée des étoiles aléatoirement sur une surface donnée. En réalité, cela va créer des box-shadow
pour un seul élément.
On l’appelle comme ceci :

500
correspond au nombre d’étoiles qui seront créées, 1800
à la surface maximum où les étoiles seront placées aléatoirement.
La ceinture d’astéroïdes
Un peu astucieux également du côté de la ceinture d’astéroïdes puisque pour la réaliser j’ai réutilisé ma fonction stars()
.
Le problème c’est que je voulais un anneau d’étoiles
Pour ce faire, mon pseudo-élément qui est un disque, est aussi gros que la partie dont je ne veux pas voir. Le reste en dehors sera visible.
Encore une fois j’ai volontairement changé certaines valeurs pour les besoins de la démo.
Vous avez maintenant toutes les clés pour réaliser ce système solaire ! Si vous êtes perdus, vous pouvez toujours regarder la source sur le résultat ci-dessous.
Le résultat final
Je vous invite à voir le résultat en plein écran, pour le code c’est par ici !