Problème de vue

Problème de vue

J'ai vu un dessin qui ressemblait à ça et je me suis dit que ce serait amusant si les yeux bougeaient. C'était une démo pour faire des cercles. La bouche était également un cercle fixe et il n'y avait pas de nez.

La technique est simple. Le cercle pour les yeux sont des carrés blancs (balise <div>) avec une bordure noire. Le cercle est obtenu avec la propriété border-radius. Les pupilles sont des carrés noirs de la même dimension que les yeux. Pour ne conserver que la pupille j'utilise la propriété clip-path avec la fonction circle().

Le nez est un rectangle avec une bordure sur les côtés de gauche et du bas et déformé avec la propriété transform accompagnée de la fonction skewx().

Le mouvement des yeux utilise également la propriété transform avec la fonction rotate(). Par défaut, l'axe sur lequel tourne l'élément est le centre de l'élément ce qui nous permet de ne pas utiliser la propriété transform-origin. Pour les animer, on fait appel à la propriété animation et aux règles @keyframes. C'est le même principe pour la langue. Dans son cas, on joue sur la propriété visibility qui prend hidden ou visible comme valeur.


<style>
/* Le carré rouge */
#bloc {
  width: 304px;
  height: 304px;
  background-color: red;
  border: 1px dotted black;
}

/* Le grand rond */
#tete {
  position: absolute;
  width: 300px;
  height: 300px;
  background-color: white;
  border: 2px solid black;
  border-radius: 50%;
}

/* Les deux ronds pour les yeux */
.oeil {
  position: absolute;
  width: 80px;
  height: 80px;
  background-color: white;
  border: 2px solid black;
  border-radius: 50%;
}

/* Position oeil gauche */
#gauche {
  left: 60px;
  top: 120px;
}

/* Position oeil droit */
#droit {
  left: 180px;
  top: 120px;
}

/* Pupille oeil gauche */
#pupilleG {
  position: absolute;
  left: 0px;
  top: 0px;
  width: 80px;
  height: 80px;
  clip-path: circle(8px at center 65px);
  background-color: black;
  transform: rotate(45deg);
  animation: 2s G linear infinite alternate;
}

/* Pupille oeil droit */
#pupilleD {
  position: absolute;
  left: 0px;
  top: 0px;
  width: 80px;
  height: 80px;
  clip-path: circle(8px at center 65px);
  background-color: black;
  transform: rotate(45deg);
  animation: 6s D linear infinite alternate;
}

/* Déplacement oeil gauche */
@keyframes G {
  from { transform: rotate(45deg); }
    to { transform: rotate(-45deg); }
}

/* Déplacement oeil droit */
@keyframes D {
  from { transform: rotate(45deg); }
   33% { transform: rotate(45deg); }
   66% { transform: rotate(-45deg); }
    to { transform: rotate(-45deg); }
}

/* Le nez */
#pif {
  position: absolute;
  width: 20px;
  height: 60px;
  left: 145px;
  top: 190px;
  border-left: 2px solid black;
  border-bottom: 2px solid black;
  transform: skewx(-25deg);
}

/* La bouche */
#bouche {
  position: absolute;
  width: 120px;
  height: 20px;
  left: 100px;
  top: 290px;
  border-radius: 20px 20px 60px 60px;
  background-color: deeppink;
  opacity: .4;
}

/* La langue */
#langue {
  position: absolute;
  width: 30px;
  height: 30px;
  left: 140px;
  top: 300px;
  background-color: red;
  transform: skewx(-15deg);
  clip-path: ellipse(15px 30px at top center);
  animation: 6s langue linear infinite alternate;
  visibility: hidden;
}

/* La langue qui sort */
@keyframes langue {
    0% { visibility: hidden; }
   44% { visibility: hidden; }
   45% { visibility: visible; }
   55% { visibility: visible; }
   56% { visibility: hidden; }
  100% { visibility: hidden; }
}
</style>

Le code HTML se passe de commentaires, c'est une suite de balises <div>. Seule remarque, l'utilisation de la classe "oeil" qu'on utilise deux fois et qui décrit le cercle formant l'oeil. On distingue l'oeil droit du gauche par leur identifiant.

<div id="bloc">
    <div id="tete"></div>
    <div class="oeil" id="gauche">
        <div id="pupilleG"></div>
    </div>
    <div class="oeil" id="droit">
        <div id="pupilleD"></div>
    </div>
    <div id="pif"></div>
    <div id="bouche"></div>
    <div id="langue"></div>
</div>