Les transformations 3D en CSS3

debray jerome

Voici un article traitant des transformations dans un plan 3D. Nous allons voir les différentes propriétés CSS3 permettant de le faire, ainsi que des exemples concrets sur ce que l'on peut obtenir.

Compatibilité : Safari et partiellement pour Chrome.

Commentez

- Titre : Les transformations 3D en CSS3

- Auteur : debray jerome

- Parution : 14 mars 2011

- Licence : Copyright ® 2011 debray jerome. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. La perspective

- III. Les transformations 3D

- IV. preserve-3D

- V. Exemples

- VI. Le cube

- VII. Le flip

- VIII. Interaction utilisateur et transition.

- IX. Exemples avec de la géométrie

- X. Conclusion

- XI. Remerciements

I - Introduction

Afin de bien visualiser les transformations 3D, utilisez le navigateur Safari qui est le seul à ce jour à fournir le meilleur support CSS3 3D. Au vu de ce que l'on peut en faire, on peut espérer que les autres navigateurs implémenteront rapidement ces nouvelles propriétés.
Celles ci sont déjà disponibles sur safari mobile, permettant ainsi de proposer des applications web plus riches visuellement sur Iphone, Ipad.

II - La perspective

La perspective est le point de fuite d'un espace 3D.

Pour activer la 3D, un élément à besoin de la perspective. On peut l'utiliser de 2 façons. Soit via la propriété transform, soit la propriété perspective.

transform : perspective(600);

perspective : 600;

La première notation via la propriété transform est utilisée quand on veut appliquer une transformation 3D sur un élément. La seconde notation est utilisée quand on veut appliquer une transformation 3D sur un ensemble d'éléments (on l'applique donc sur l'élément parent).

Perspective sur élément

Perspective sur parent

La valeur de la perspective détermine l'intensité de l'effet 3D. Plus sa valeur est élevée, plus la distance du point de fuite est élevée.

<div class="far">
</div>

.far{
-webkit-transform:perspective(600) rotateX(-45deg);
background-color:#333;
margin:10px auto;
width:200px;
height:100px;
}

<div class="notfar">
</div>

.notfar{
-webkit-transform:perspective(100) rotateX(-45deg);
background-color:#333;
margin:10px auto;
width:200px;
height:100px;
}

Enfin le point de fuite peut se positionner à un autre endroit grâce à la propriété perspective-origin :

-webkit-perspective-origin:top left;
perspective-origin:top left;

III - Les transformations 3D

Dans un article précédent, je vous avais montré les différents valeurs de la propriété transform pour la transformation 2D. Dans un espace 3D, transform peut utiliser les mêmes valeurs auxquelles s'ajoutent :

- rotateY ;

- rotateX ;

- rotateZ ;

- translateZ ;

- scaleZ.

translateZ :

Cette fonction de transformation permet de faire une translation sur l'axe Z de notre espace 3D. Si la valeur est négative, l'objet sera loin de spectateur, si elle est positive, il sera proche du spectateur.

scaleZ :

Cette fonction de transformation permet d'agrandir ou de diminuer un élément selon l'axe Z de notre espace 3D. Nous n'en parlerons pas car cette fonction n'est pas implémentée.

rotateX, rotateY, rotateZ :

Ces fonctions de transformation permettent de faire une rotation selon un axe de notre espace 3D. Si la valeur est négative, ce sera un rotation antihoraire, sinon ce sera une rotation horaire.

Exemples :

axe dans un plan 3D

Sachez qu'il existe des raccourcis afin d'utiliser ces fonctions, les voici :

- translate3d(x, y, z) ;

- scale3d(x, y, z) ;

- rotate3d(x, y, z).

ces fonctions raccourcis permettent de déclencher l'accélération matérielle sous Safari.

IV - preserve-3D

La propriété transform-style permet de définir le style de la transformation 3D. Elle peut prendre deux valeurs :

- flat (par défaut) ;

- preserve-3d.

La valeur flat indique que les éléments enfants reposent à "plat" sur leur parent.

La valeur preserve-3d indique que les éléments reposent dans le plan 3D géré par le parent.

Voici une exemple pour illustrer mes propos :

mode flat

mode preserve-3d

-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;

V - Exemples

Avec tous ce que nous avons vu précédemment, on peut donc tenter de faire quelques exemples 3D. Nous allons voir ici quelques exemples connus tels que le cube, le flip, le carrousel et également un cube avec une interaction utilisateur (sur un clic).

VI - Le cube

Le principe est le suivant : il faut tout d'abord définir un plan 3D (une div) avec une perspective qui va contenir notre bloc "cube" et celui ci va intégrer des enfants qui vont permettre d'obtenir les côtés d'un cube.
On commence donc par définir ce plan :

<div class="container">
<div id="cube">
</div>
</div>

.container{
-webkit-perspective:600;
}
#cube{
width: 200px;
height: 200px;
margin: 0 auto 40px; /*pour centrer le cube sur la page*/
-webkit-transform-style: preserve-3d;
}

A partir de là, on définit chaque côté du cube :

<div class="container">
<div id="cube">
<div id="front"><img src="http://debray.jerome.free.fr/application/images/slideshow/5.jpg" height="200"></div>
<div id="back"><img src="http://debray.jerome.free.fr/application/images/slideshow/5.jpg" height="200"></div>
<div id="right"><img src="http://debray.jerome.free.fr/application/images/slideshow/5.jpg" height="200"></div>
<div id="left"><img src="http://debray.jerome.free.fr/application/images/slideshow/5.jpg" height="200"></div>
<div id="up"><img src="http://debray.jerome.free.fr/application/images/slideshow/5.jpg" height="200"></div>
<div id="bottom"><img src="http://debray.jerome.free.fr/application/images/slideshow/5.jpg" height="200"></div>
</div>
</div>

Vous remarquerez que j'ai ajouté des images afin de styler un peu les faces du cubes.
Une fois que l'on a ces côtés, on va leur appliquer des fonctions de transformations pour les placer dans le plan 3D #cube.

Toutefois je définis au préalable des propriétés CSS communes à tous les côtés du cube. Ce qui me permet de vous présenter une nouvelle propriété CSS3 : backface-visibility.
Cette propriété permet la visibilité ou non de l'arrière un bloc - comme si on voyait l'arrière d'un bloc (et non pas à travers) - nous verrons un exemple avec le flip.
Elle prend comme valeur visible ou hidden.

J'ai ajouté de l'opacité afin que vous puissiez voir les différents côtés du cube.

#cube div{
position:absolute;
-webkit-backface-visibility: hidden;
overflow:hidden;
width:200px;
height:200px;
opacity:0.5;
}

Il nous reste plus qu'à mettre en place les propriétés CSS et donc de transformations 3D pour obtenir notre cube.

Le coté #front est la face du cube qui se situe le plus proche de nous. Nous allons faire un cube de dimensions 200px. Ainsi, nous avançons de 100px le #front via la transformation translateZ :

#front{
-webkit-transform: translateZ( 100px );
}

Pour l'arrière du cube (#back), on fait l'opération inverse :

#back{
-webkit-transform: translateZ( -100px );
}

face #front et #back

Nous allons maintenant placer les côtés droit et gauche du cube.
On va appliquer une rotation de 90 degrés sur l'axe Y pour pouvoir les placer. On ajoute également une translation de 100px afin de partir au même niveau que le coté #front

#left{
-webkit-transform: rotateY( 90deg ) translateZ( 100px );
}
#right{
-webkit-transform: rotateY( -90deg ) translateZ( 100px );
}

Enfin pour placer les côtés du haut et du bas, on fait la même chose que précédemment mais avec une rotation sur l'axe X.

#up{
-webkit-transform: rotateX(90deg) translateZ( 100px );
}
#bottom{
-webkit-transform: rotateX(-90deg) translateZ( 100px );
}

Enfin, nous allons réorienter le cube en entier afin de mieux voir le rendu.

#cube{
width: 200px;
height: 200px;
margin: 0 auto 40px;
-webkit-transform-style: preserve-3d;
-webkit-transition: -webkit-transform 2s;
-webkit-transform: translateZ(-100px) rotateX( -220deg ) rotateY( 45deg );
}

Nous allons terminer cette exemple en ajoutant une animation sur le cube pour qu'il puisse tourner sur lui même en continue.
Pour cela on ajoute une classe sur notre cube qui a pour propriété une animation CSS. (j'ai également supprimé l'opacité sur les côtés du cube).

#cube.rotation {
-webkit-animation: rotateCube 8s infinite ease-in-out;
}
/*animation css*/
@-webkit-keyframes rotateCube {
0% {
-webkit-transform: translateZ( -100px ) rotateX(   0deg ) rotateY(   0deg );
}
100% {
-webkit-transform: translateZ( -100px ) rotateX( 360deg ) rotateY( 360deg );
}
}

<div class="container">
<div id="cube" class="rotation">
...
</div>
</div>

Voir la démo.

VII - Le flip

C'est un effet assez courant sur le web. Le principe est assez simple. Il s'agit de deux blocs juxtaposés qui lorsque l'on clique subissent une rotation de 180 degrés. Cela donne une impression de retournement de carte.

Dans un premier temps, on crée le plan 3D avec une perspective :

<div class="containerFlip">
<div id="flip">

</div>
</div>

.containerFlip {
width: 150px;
height: 300px;
position: relative;
margin: 0 auto 40px;
border: 1px solid #CCC;
-webkit-perspective: 800;
}
#flip{
width:100%;
height:100%;
position:absolute;
-webkit-transition: -webkit-transform 1s;
-webkit-transform-style: preserve-3d;
}

Vous remarquerez que j'ai mis une transition (-webkit-transition) permettant ainsi de donner une animation lors du retournement de la carte.

A partir de là, j'ajoute ma carte et plus précisément ces deux côtés (face avant et face arrière).

<div class="containerFlip">
<div id="flip">
<div id="faceA">A</div>
<div id="faceB">B</div>
</div>
</div>

#faceA, #faceB{
display:block;
width:100%;
height:100%;
background:#069;
position:absolute;
-webkit-backface-visibility: hidden;
}
#faceB{
background:#900;
-webkit-transform:rotateY(180deg);
}

J'ajoute aux deux cotés la propriété -webkit-backface-visibility à la valeur hidden. Si je ne mets pas cette propriété, lors du retournement de la carte j'aurai un problème de background lors de l'animation (scintillement entre les couleurs des deux côtés). Ce problème est dû au fait que le -webkit-backface-visibility à visible rendrait visible l'arrière de mon bloc lors du retournement.
Enfin la face arrière (#faceB) subira une rotation de 180 degrés sur l'axe Y afin d'être bien positionné lors du retournement de la carte.

Pour terminer je rajoute en Javascript (ici jQuery), une fonction sur le clic de la carte pour lancer le retournement de la carte. Cette fonction ajoutera ou nom une classe au bloc #flip.

<script type="text/javascript">
$(function(){
$('#flip').click(function(){
$(this).toggleClass('flipMe');
});
});
</script>

#flip.flipMe{
-webkit-transform:rotateY(180deg);
}

Voir la démo.

VIII - Interaction utilisateur et transition.

Reprenons notre exemple du cube. Sur un hover nous pouvons interagir avec notre forme 3D.

Voir la démo.

Allons plus loin et établissons une interaction via un clic en Javascript:

Voir la démo.

IX - Exemples avec de la géométrie

On peut très bien utiliser d'autres formes que le carré et le rectangle. Par exemple le rond, le triangle, l'ovale et j'en passe.

Voici une ébauche de maison en 3D (avec rollover) : Voir la démo.

X - Conclusion

Les transformations 3D en CSS3 sont simples à mettre en oeuvre et permettent d'innombrables possibilités. Couplé au Javascript, nous pouvons mettre en oeuvre des applications web contenant des animations très poussées. Par contre vous noterez le manque de support de ces propriétés dans les navigateurs autres que de type webkit (Safari (sous PC, Iphone ou Ipad) et Chrome - et encore, on a une compatibilité partielle sous Chrome).

XI - Remerciements

Merci à djibril pour sa relecture attentive.