Rubrique fourre-tout : Fabriquer un dé en CSS (animation)

Fabriquer un dé en CSS

Les 6 faces du dé telles que nous les propose le système.

Pour les utiliser dans une page il faut utiliser les caractères ⚀ pour ⚀, ⚁ pour ⚁, ⚂ pour ⚂, ⚃ pour ⚃, ⚄ pour ⚄ et ⚅ pour ⚅. J'ai préféré faire des gifs transparents plus faciles à manipuler. Je les ai colorés dans le code CSS (.face1, .face2 etc.). Vous pouvez les enregistrer dans le même dossier que votre page html si vous voulez reproduire l'animation plus bas.

           

Pour dessiner le dé, j'ai pris un dé du commerce comme modèle.

Vous pouvez remarquer, pour ceux qui l'ignoraient, que la disposition des faces n'est pas anodine. Deux faces opposées ont un total de 7 points. Le 6 est opposé au 1, le 5 est opposé au 2 et le 4 est opposé au 3. Ça nous fait un total de 21 points.

Pour les amateurs du jeu de Yam's, vous avez là l'explication du bonus que l'on obtient en faisant 63 ou plus au total des dés. Il suffit de faire 6 séries de trois dés identiques pour obtenir les 63 points.



Pour arrêter l'animation, passez la souris dessus.


Le code HTML est particulièrement simple. Il suffit d'empiler les faces les unes sur les autres. La face 5 étant en bas de la pile et la face 3 sur le dessus.

<div id="animDE">
    <div class="face5" id="anim5"></div>
    <div class="face2" id="anim2"></div>
    <div class="face1" id="anim1"></div>
    <div class="face4" id="anim4"></div>
    <div class="face6" id="anim6"></div>
    <div class="face3" id="anim3"></div>
</div>

Le code CSS peut paraitre un peu long mais ce ne sont pratiquement que des répétitions; Il y a six faces donc six animations.

Tout d'abord, il y a le descriptif des faces avec la mise en couleur.

Ensuite, vient le carré en pointillé dans lequel vient s'inscrire le dé. Il est suivi par le blocage des animations quand on passe la souris sur le carré Il faut répéter l'opération 6 fois sinon ça ne fonctionnera pas correctement.

Plus bas, on a les positions de départ des animations avec la déclaration de l'animation. A noter que je les ai baptisées un, deux, trois..., c'est plus facile pour me repérer.

Pour terminer, on a les règles @keyframes qui décrivent l'évolution des faces pendant l'animation.

/* Les faces de dé du système */
.de {
  font-size: 100px;
}

/* les six faces du dé */
/* ******************* */
.face1 {
  background: url("1.gif");
  background-color: rgba(0, 0, 255, .44);
  background-size: 100% 100%;
  width: 120px;
  height: 120px;
}
.face2 {
  background: url("2.gif");
  background-color: rgba(0, 255, 0, .4);
  background-size: 100% 100%;
  width: 120px;
  height: 120px;
}
.face3 {
  background: url("3.gif");
  background-color: rgba(255, 0, 0, .4);
  background-size: 100% 100%;
  width: 120px;
  height: 120px;
}
.face4 {
  background: url("4.gif");
  background-color: rgba(0, 255, 255, .4);
  background-size: 100% 100%;
  width: 120px;
  height: 120px;
}
.face5 {
  background: url("5.gif");
  background-color: rgba(255, 0, 255, .4);
  background-size: 100% 100%;
  width: 120px;
  height: 120px;
}
.face6 {
  background: url("6.gif");
  background-color: rgba(255, 255, 0, .4);
  background-size: 100% 100%;
  width: 120px;
  height: 120px;
}

/* Le repère pointillé autour du dé reconstitué */
/* ******************************************** */
#animDE {
  float: left;
  position: relative; 
  width: 180px; 
  height:180px;
  border: 1px dotted black;
  margin-left: 240px;
}
/* On bloque chacune des 6 animations */
#animDE:hover #anim1 { animation-play-state: paused; }
#animDE:hover #anim2 { animation-play-state: paused; }
#animDE:hover #anim3 { animation-play-state: paused; }
#animDE:hover #anim4 { animation-play-state: paused; }
#animDE:hover #anim5 { animation-play-state: paused; }
#animDE:hover #anim6 { animation-play-state: paused; }

/* Positions des faces du dé au début de l'animation */
/* ************************************************* */
#anim1 {
  position: absolute; 
  width: 120px; 
  top: -120px;
  left: -120px;
  animation: un 10s ease infinite alternate;
}
#anim2 {
  position: absolute; 
  width: 120px; 
  top: -120px;
  left: -120px;
  animation: deux 10s ease infinite alternate;
}
#anim3 {
  position: absolute; 
  width: 120px; 
  top: -120px;
  left: -120px;
  animation: trois 10s ease infinite alternate;
}
#anim4 {
  position: absolute; 
  width: 120px; 
  top: -120px;
  left: -120px;
  animation: quatre 10s ease infinite alternate;
}
#anim5 {
  position: absolute;      
  width: 120px; 
  top: -120px;
  left: -120px;
  animation: cinq 10s ease infinite alternate;
}
#anim6 {
  position: absolute; 
  width: 120px; 
  top: -120px;
  left: -120px;
  animation: six 10s ease infinite alternate;
}

/* Scripts des animations */
/* ********************** */
@keyframes cinq {
    0% {
        top: -120px; 
        left: -120px;
        transform: skewy(0deg);
        position: relative; 
        }
   10% {
        top: -120px; 
        left: -120px;
        transform: skewy(0deg);
        position: relative; 
        }
   40%  { position: absolute; 
          top: 60px;
          left: 120px;
          transform-origin: left bottom;
          transform: skewy(-45deg) rotate(-360deg);
          width: 60px;       
        }
  100%  { position: absolute; 
          top: 60px;
          left: 120px;
          transform-origin: left bottom;
          transform: skewy(-45deg) rotate(-360deg);
          width: 60px;       
        }
}
@keyframes deux {
    0% {
        top: -120px; 
        left: -120px;
        transform: skewy(0deg);
        position: absolute; 
        }
    20% {
        top: -120px; 
        left: -120px;
        transform: skewy(0deg);
        position: absolute;
        }
   50%  { position: absolute; 
          top: 30px;
          left: 0px;
          transform: skewy(-45deg) rotate(360deg);
          width: 60px;       
        }
  100%  { position: absolute; 
          top: 30px;
          left: 0px;
          transform: skewy(-45deg) rotate(360deg);
          width: 60px;       
        }
}
@keyframes un {
    0% {
        top: -120px; 
        left: -120px;
        position: absolute; 
        }
    30% {
        top: -120px; 
        left: -120px;
        position: absolute;
        }
   60%  { position: absolute; 
          top: 0px;
          left: 60px;
          transform: rotatex(360deg) rotatey(-360deg);
          width: 120px;       
        }
  100%  { position: absolute; 
          top: 0px;
          left: 60px;
          transform: rotatex(360deg) rotatey(-360deg);
          width: 120px;       
        }
}
@keyframes quatre {
    0% {
        top: -120px; 
        left: -120px;
        position: absolute; 
        }
    40% {
        top: -120px; 
        left: -120px;
        position: absolute;
        }
    70% { position: absolute; 
          top: 120px;
          left: 0px;
          transform-origin: left bottom;
          transform: skewx(-45deg) rotatex(-360deg) rotatey(360deg);
          width: 120px;       
          height: 60px;       
        }
   100% { position: absolute; 
          top: 120px;
          left: 0px;
          transform-origin: left bottom;
          transform: skewx(-45deg) rotatex(-360deg) rotatey(360deg);
          width: 120px;       
          height: 60px;       
        }
}
@keyframes six {
    0% {
        top: -120px; 
        left: -120px;
        position: absolute; 
        }
    50% {
        top: -120px; 
        left: -120px;
        position: absolute;
        }
    80% { position: absolute; 
          top: 60px;
          left: 0px;
          transform-origin: left bottom;
          transform: skewx(-45deg);
          width: 120px;       
          height: 60px;       
        }
   100% { position: absolute; 
          top: 60px;
          left: 0px;
          transform: skewx(0deg);
          width: 120px;       
          height: 120px;       
        }
}
@keyframes trois {
    0% {
        top: -120px; 
        left: -120px;
        position: absolute; 
        }
    60% {
        top: -120px; 
        left: -120px;
        position: absolute;
        transform-origin: left bottom;
        }

    75% { position: absolute; 
          top: -120px;
          left: 60px;
          transform: skewx(-45deg);
          width: 120px;       
          height: 60px;       
        }
    90% { position: absolute; 
          top: 0px;
          left: 30px;
          transform: skewx(-45deg);
          width: 120px;       
          height: 60px;       
        }
   100% { position: absolute; 
          top: 0px;
          left: 30px;
          transform: skewx(-45deg);
          width: 120px;       
          height: 60px;       
        }
}

On emploie quelques mots-clés dans cette animation:
width et height qui fixent la taille des faces du dé pendans l'animation.
background et les propriétés qui s'y rapportent qui décrivent l'aspect des faces du dé.
float et position afin de maitriser l'espace dans lequel évolue le dé.
margin-left nous permet de décaler l'animation vers la droite afin qu'elle ne déborde pas en dehors de l'écran sur la gauche. border sert à dessiner le pointillé autour du bloc qui reçoit le dé.
top et left servent au placement des faces du dé.
animation décrit le éplacement de chaque face du dé.
@keyframes, ce sont les règles qui écrivent le script pour chaque animation des faces du dé. Eles utilisent transform conjointement avec les fonctions skewx et skewy pour les déformations et rotatex et rotatey pour les rotations. On utilise également transform-origin qui déplace le centre de gravité des éléments.

Afin que l'on puisse voir ce qui se passe dans l'animation à un moment donné, on utilise la pseudo-classe :hover et animation-play-state. Cette façon de procéder est particulièrement utile lorsque l'on met au point une animation. Par exemple, dans l'animation Mongolfière, ça m'a permis de préciser les moment où la mongolfière change de direction et de taille.