CSS 3 permet de modéliser des transformations géométriques (en géométrie repérée) directement dans une page web.
Pour profiter au mieux des animations (dernier onglet de l’article), un clic droit sur l’icône HTML d’une animation, suivi de « ouvrir le lien dans une nouvelle fenêtre » donne une pleine fluidité dans les animations.
par Alain Busser, Aymeric Picaud
Dans l’article sur Python en lycée, l’un des auteurs s’est permis d’utiliser la concision de Python pour traiter des points du programme de lycée sur lesquels l’utilisation de Python n’est pas prévue : la géométrie repérée. Dans le programme de mathématiques du lycée mis en place en 2017, la géométrie repérée porte essentiellement sur le calcul de coordonnées (points, vecteurs) et les équations (de droites, de cercles). Mais les transformations géométriques sont intéressantes à traiter avec les coordonnées, ne serait-ce que parce qu’elles sont au programme du collège.
La géométrie repérée des transformations du plan peut être faite en Python qui est le langage de programmation au lycée (et pas qu’en maths), mais de fait, il n’est pas nécessaire d’utiliser de langage de programmation du tout : CSS3 suffit pour calculer des transformations parmi lesquelles les symétries axiales, les rotations (y compris la symétrie centrale) et les homothéties. Dans cet article, on présente un TD effectué en première NSI, portant sur ces transformations et leurs animations. Il s’agit donc de montrer des transformations au programme du collège avec la géométrie repérée. Un défi...
Cet article est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 2.0 France.
Le langage CSS3 permet de modifier l’aspect d’une page web. Parmi ses nombreuses possibilités, il y a la taille et l’orientation des objets de la page, ce qui constitue une introduction possible aux transformations géométriques du plan (voire de l’espace). Pour voir l’effet de ces transformations, il est utile de les appliquer à un objet qui n’a pas trop de symétries. Par exemple un texte comme Tao.
html
Le style CSS s’appliquant à une page web au format html, on va commencer par montrer comment créer et afficher une page web :
- pour la créer et la modifier, il faut un éditeur de texte (notepad ou sublime text sous Windows, simple text sous MacOS, vi ou Emacs sous Linux, VS Codium ou Geany sous toutes plateformes,...)
- pour l’afficher, il faut un navigateur internet comme Edge, Chrome, Firefox etc.
De toute manière, on peut se passer de l’éditeur de texte, en se servant de sites web permettant d’écrire directement du html ou du Css dans la page. Par exemple https://jsFiddle.
Avec un navigateur Internet, un clic droit sur un élément de la page (un mot ou un paragraphe par exemple) permet de l’inspecter, par exemple de connaître ses dimensions, sa couleur etc.
On apprend alors que chaque élément html est inclus dans un rectangle. C’est à ce rectangle qu’on va appliquer l’une des transformations au programme du collège :
- translation
- symétrie axiale
- rotation (en particulier symétrie centrale)
- homothétie.
Texte
En Html, tous les éléments sont dans des balises, c’est-à-dire des éléments compris entre
- une parenthèse ouvrante notée
<balise>
- et la parenthèse fermante qui lui correspond, notée
</balise>
Pour écrire le mot Tao dans une page web, on peut le mettre dans un rectangle de classe p (un paragraphe), ou h2 (un titre de niveau 2) ou tout simplement div (un rectangle quelconque). Ici on choisira un h2, ce qui donne :
corps
Cependant, pour que ce texte s’affiche dans le navigateur Internet, il faut le mettre, non pas dans l’entête head (qui ne s’affiche pas) mais dans le corps body (tout ce qui s’affiche dans la page). Il faut donc écrire
Mais ce n’est pas tout : la totalité du code doit être dans une balise html ce qui donne, pour la page web, le code minimal
Dans le navigateur, on obtient alors ceci :
entête
Le html ne comprend pas que le corps (body) mais également des choses à ne pas afficher, comme le code JavaScript, le choix du langage utilisé, le titre de la page... ou le CSS. Celui-ci est disposé dans une balise style, elle-même disposée dans l’entête head. Le code complet de la page sera alors
Les lignes vides sont celles où on inscrira le code CSS (effets de style). Par exemple si on veut que tous les h2 soient écrits en bleu, on écrit
ce qui produit cet effet dans le navigateur :
Dans la suite, on laissera les lettres en noir. Mais on leur appliquera des transformations du plan (la page web est un morceau de plan)
Repère
La page web est munie d’un repère, mais celui-ci n’est pas comme dans le cours de maths :
- l’unité est, par défaut, le pixel noté
px
- l’axe des abscisses est bien horizontal et orienté vers la droite, mais l’axe des ordonnées est dirigé vers le bas
- l’origine du repère est en haut à gauche de la page.
Les distances seront donc notées comme ceci : 200px
(pour une distance de 200 pixels), et les angles seront notés ainsi : 90deg
(pour un angle droit). En effet, en CSS, l’unité de base pour les angles est le degré.
Noter que les angles comme les distances sont potentiellement négatifs, ce qui permet de parler de coordonnées d’un élément. Simplement, si l’abscisse est négative, le transformé sera à gauche, et si l’ordonnée est négative, le transformé sera en haut.
Lorsqu’une distance (par exemple l’ordonnée d’un vecteur de translation horizontal) est nulle, il n’est pas nécessaire de préciser son unité. Ainsi, 0px, 0cm, 0%, 0deg sont toutes égales à 0 tout court. C’est une illustration de la linéarité des changements d’échelle : il y a proportionnalité lorsque la droite passe par l’origine.
Translation
La translation est une transformation que l’on peut appliquer à du texte comme toutes les autres transformations (voir plus loin). Mais on peut aussi appliquer une translation à une copie du texte, avec text-shadow
qui simule une ombre portée. L’ombre est déterminée par trois longueurs (en pixels) :
- l’abscisse du vecteur de la translation
- l’ordonnée de ce vecteur
- le rayon de flou.
On omettra ce dernier pour que l’ombre soit nette et qu’on voie bien l’image du texte par la translation. Par contre : on donnera la couleur bleue au texte translaté (l’ombre) afin de bien distinguer l’antécédent (en noir) et l’image (en bleu). Par exemple si le texte bleu est l’image du texte noir par la translation de vecteur (64,32), on écrira ce code dans la balise style :
- h2 {
- text-shadow: 64px 32px blue;
- }
on obtient alors cette image :
Voici le code html complet :
Dans la suite on ne donnera que le code css qui est dans la balise style.
transformations
Dans les onglets suivants, on montrera la page originale (sans Css) et sa version transformée pour la comparaison. On montrera des exemples de
- translation
- symétrie axiale
- rotations
- homothétie
translation
Pour appliquer à un texte h2 une translation de vecteur (64,32) on met dans le style
- h2 {
- transform: translate(64px,32px);
- }
La page
devient alors
symétrie
La seule transformation qui est au programme de cycle 3 (symétrie axiale) voire avant, est plus compliquée à conceptualiser en Css, car c’est une rotation de 180 degrés en dehors de la page, autour d’un axe qui est dans la page. L’idée sous-jacente est que si on veut retourner une carte (passer du verso au recto), on la fait bel et bien tourner en la soulevant puis en la reposant sur la table. Pour peu que la carte soit en papier transparent, on voit effectivement une symétrie axiale se mettre en œuvre.
- une symétrie d’axe vertical (médiane de la page et non du texte) est une rotation autour de l’axe des Y :
- h2 {
- transform: rotateY(180deg);
- }
transformera
en
- une symétrie d’axe horizontal est une rotation autour de l’axe des abscisses :
- h2 {
- transform: rotateX(180deg);
- }
Elle transformera la page
en
rotations
L’effet le plus impressionnant en NSI, est la rotation. Si on veut faire tourner le texte de 45 degrés dans le sens trigonométrique on fait
- h2 {
- transform: rotate(-45deg);
- }
En effet, on rappelle que le repère Html est inversé, avec des ordonnées croissantes vers le bas. Si on avait mis 45deg au lieu de -45deg le texte serait sorti de l’écran (par le haut). En effet le centre de rotation est en bas à droite du texte.
La page
devient sous l’effet de cette transformation :
En fait il est parfaitement possible de dessiner quand même un texte tourné de 45 degrés dans le sens des aiguilles d’une montre : il suffit d’appliquer d’abord une translation vers le bas, avant d’appliquer une rotation au résultat :
- h2 {
- transform: translate(0,160px) rotate(45deg);
- }
Avec cette combinaison de translation et rotation, la page
est transformée en
Et la symétrie centrale ? C’est tout simplement une rotation de 180 degrés :
- h2 {
- transform: rotate(180deg);
- }
Elle transforme la page
en
Homothéties
Une homothétie est un changement d’échelle (scale en anglais... et en Css). Par exemple pour tripler la taille du texte, on peut faire simplement
- h2 {
- transform: scale(3) translate(160px,20px);
- }
La page
est alors transformée en
Avec Chromium, le centre de l’homothétie est en bas à droite du texte, et si on n’applique pas de translation au résultat, le texte agrandi sort de la page. Pour y remédier, on peut raisonner non en terme de transformation, mais directement de taille de texte, avec
- h2 {
- font-size: 300%;
- }
Ce qui donne une version légèrement différente de la précédente :
On peut en fait retrouver la symétrie centrale, comme homothétie de rapport -1 :
- h2 {
- transform: scale(-1);
- }
donne la même page que la rotation de 180 degrés : elle transforme
en
Composition
Il est possible de composer des transformations Css. Cela permet de faire découvrir expérimentalement que
- la composée de deux translations est une translation
- l’ordre dans lequel on compose ces translations ne change pas le résultat
- idem pour les rotations
- la composée d’une rotation et d’une translation est une rotation (où est son centre ?)
- la composée d’une translation et d’une homothétie est une homothétie (où est son centre ?)
- la composée de deux symétries axiales est une rotation.
Ce dernier fait peut être testé avec la question suivante : Quel est l’effet de la transformation Css ci-dessous ?
- h2 {
- transform: rotateX(180deg) rotateY(180deg);
- }
(un indice : c’est une transformation déjà vue)
On peut même découvrir les similitudes directes (hors programme) en les définissant comme composées d’une translation, d’une rotation et d’une homothétie. Mais là, on sort clairement du programme du collège. On peut d’ailleurs définir une similitude directe par une matrice, et même représenter les transformations du plan par des matrices, par exemple une symétrie d’axe incliné à 45 degrés peut s’obtenir avec
- h2 {
- transform: matrix(0,1,1,0,0,160);
- }
Les deux derniers coefficients sont ceux de la translation. La page
est transformée en
Invariants
Pour résoudre le problème des translations parfois nécessaires pour que le texte transformé ne soit pas hors de la page, on peut centrer le texte, ainsi :
- h2 {
- text-align: center;
- transform: rotate(-45deg);
- }
On voit le texte tourné sans avoir à appliquer une translation :
Cela permet la possibilité qu’après avoir appliqué une transformation à un texte, ce texte reste identique à la version non transformée. La question de détecter les textes invariants par certaines transformations, est source de nombreux exercices classiques au collège, mais avec un habillage web 2.0.
Axe horizontal
On propose ce genre d’exercice :
Voici le source d’un fichier html :
Le rendu dans un navigateur web est
- Quelle transformation a été appliquée au mot Tao pour obtenir ce rendu ?
- On décide d’appliquer la même transformation au mot BIDOCHE à l’aide de ce code html :
Que constate-t-on ?
- Donner un autre mot français (écrit en majuscule) qui a la même propriété.
- Donner les lettres de l’alphabet (en majuscules) ayant la même propriété.
- Combien y a-t-il de nombres de deux chiffres (premier chiffre non nul) ayant la même propriété ?
Axe vertical
On propose ce genre d’exercice :
Le fichier html suivant
donne, dans un navigateur Internet, l’affichage de page suivant :
- Quelle transformation a-t-elle été appliquée au texte Tao pour avoir un tel résultat ?
- On décide d’appliquer la même transformation au texte AVA avec ce code html :
Quel résultat obtient-on ?
- Combien y a-t-il de nombres dont l’écriture en chiffres romains possède la même propriété ?
- Combien y a-t-il de nombres de trois chiffres (premier et dernier chiffre non nuls) dont l’écriture décimale possède la même propriété ?
Centre de symétrie
Le fichier html suivant :
produit l’affichage suivant :
- Quelle transformation a-t-elle été appliquée au texte Tao pour obtenir cet affichage ?
- On souhaite appliquer la même transformation au texte SONOS avec ce code html :
Quel est l’effet obtenu ?
- Donner un exemple de mot ayant la même propriété.
- Combien de lettres (en majuscule) ont-elles la même propriété ?
- Combien de nombres de deux chiffres (non nuls) ont-ils la même propriété ?
- Comment appelle-t-on les angles des lettres N et Z ?
fonctions
En Css3, les fonctions sont données par des tableaux de valeurs, avec interpolation automatique (pour calculer les valeurs intermédiaires) par Css. On va voir deux cas :
- les dégradés (couleur fonction de l’abscisse)
- les animations (position fonction du temps)
dégradés
On se propose de garder le mot Tao mais comme ce mot est inclus dans un rectangle, on va colorier ce rectangle de telle manière que le côté le plus à gauche soit blanc (c’est mieux pour arriver à lire le texte) mais que le côté le plus à droite soit noir. On veut donc
- du blanc à la position 0% (tout à gauche),
- du noir à la position 100% (tout à droite).
On peut y arriver avec le code que voici :
dans lequel il est précisé que le gradient est tourné de 90 degrés (sinon il serait dirigé selon l’axe des ordonnées). Le fichier ressemble à ceci :
Remarque : on a fait un choix arbitraire en considérant que le nombre 1 représente une quantité maximale de noir. Si on veut utiliser des nombres, on peut coder des valeurs de gris avec
rgb(255,255,255)
pour le gris le plus clair possible (pas de noir du tout), et
rgb(0,0,0)
pour le gris le plus foncé possible (que du noir).
Les fonctions ne sont pas toutes croissantes. Comment avoir une fonction qui monte et ensuite, descend (comme la fonction du boulanger) ? Il suffit de mettre une clé à une valeur intermédiaire (ici, 50%) et de remettre du blanc plus loin (à 100% par exemple) :
- h2 {
- background:linear-gradient(90deg, white 0%, black 50%, white 100%);
- }
ce qui donne l’effet suivant :
On peut continuer, avec une fonction qui est décroissante sur l’intervalle du milieu, et croissante avant et après :
- h2 {
- background:linear-gradient(90deg, white 0%, black 33%, white 67%, black 100%);
- }
qui produit cet effet :
croissance
On a vu un exemple de fonction croissante linéaire :
- h2 {
- background:linear-gradient(90deg, white 0%, black 100%);
- }
qui produit cet effet :
Mais l’effet n’est pas le même avec une fonction qui croit d’abord vite, ensuite plus lentement :
codée par
- h2 {
- background:linear-gradient(90deg, white 0%, grey 75%, black 100%);
- }
ou une fonction qui croit lentement puis accélère :
On peut faire des choses bien plus complexes avec cette fonction qui, une fois presque arrivée, recule pour mieux sauter :
- h2 {
- background:linear-gradient(90deg, white 0%, darkgrey 25%, lightgrey 75%, black 100%);
- }
Le rendu semble effectivement assez complexe :
animations
Comme pour les dégradés, les animations sont des fonctions définies par des points clés et interpolées entre ces points clés. Les clés s’appellent des keyframes et sont typiquement exprimées en pourcentages. À chaque pourcentage (du total de l’animation) des transformations Css sont appliquées. Par exemple si on veut que le texte Tao glisse de gauche à droite en 8 secondes, on dit qu’au début (0 pourcent) il est à sa valeur initiale (translation de vecteur nul) et au bout de 8 secondes il est tout à droite (translation de vecteur 100 pourcent de la largeur de la page). Ce qu’on écrit ainsi :
- h2 {
- animation: glisser 8s;
- animation-timing-function: linear;
- }
- @keyframes glisser {
- 0% {transform: translate(0);}
- 100% {transform: translate(100%);}
- }
Cela produit l’effet suivant :
La translation est maintenant animée, ce qui permet de voir les étapes intermédiaires et de conceptualiser les transformations comme déplacements (avec les étapes intermédiaires). Mais c’est aussi un autre regard sur les fonctions. Pour la suite on va changer de fonction : au lieu d’une fonction linéaire, on propose une fonction affine par morceaux qui monte puis descend :
- h2 {
- animation: glisser 8s;
- animation-timing-function: linear;
- }
- @keyframes glisser {
- 0% {transform: translate(0);}
- 50% {transform: translate(100%);}
- 100% {transform: translate(0%);}
- }
qui donne l’effet suivant (le mot revient en arrière une fois qu’il a fini sa promenade) :
En fait, il suffit de faire varier linéairement l’ordonnée en même temps :
- h2 {
- animation: glisser 8s;
- animation-timing-function: linear;
- }
- @keyframes glisser {
- # 0% {transform: translate(0,0);}
- 50% {transform: translate(100%,200px);}
- 100% {transform: translate(0%,400px);}
- }
pour que le mot parcoure la représentation graphique de la fonction (tournée puisqu’on a interverti abscisses et ordonnées) :
On peut aussi illustrer la notion de fonction par d’autres quantités qui varient au cours du temps :
- une rotation animée (ici, d’angle 180 degrés, c’est donc une symétrie centrale) :
- h2 {
- text-align: center;
- animation: tourner 8s;
- animation-timing-function: linear;
- }
- @keyframes tourner {
- 50% {transform: rotate(180deg);}
- 100% {transform: rotate(0);}
- }
qui donne ceci :
- une homothétie animée :
- h2 {
- text-align: center;
- animation: grandir 8s;
- animation-timing-function: linear;
- }
- @keyframes grandir {
- 50% {transform: scale(4);}
- 100% {transform: scale(1);}
- }
qui donne cet effet :
- une symétrie animée d’axe vertical :
- h2 {
- text-align: center;
- animation: symetrie 8s;
- animation-timing-function: linear;
- }
- @keyframes symetrie {
- 50% {transform: rotateY(180deg);}
- 100% {transform: rotateY(0);}
- }
qui donne ceci :
- une symétrie animée d’axe horizontal :
- h2 {
- text-align: center;
- animation: symetrie 8s;
- animation-timing-function: linear;
- }
- @keyframes symetrie {
- 50% {transform: rotateX(180deg);}
- 100% {transform: rotateX(0);}
- }
qui donne ceci :
Css pour le prof
L’un des auteurs a déjà eu l’occasion de créer des fichiers avec figures animées en Css pour les intégrer à Moodle. Il s’agissait d’un cours (sur Moodle).