Gabriel-Rambault.fr

Sommaire

Faire un cube Photos en 3D

Désolé, ne fonctionne pas avec Explorer.
Le meilleur fonctionnement est obtenu avec Firefox

Réalisation :

Ouvrir Notepad++

Nous avons préalablement préparé et dimensionné nos photos.

Créons les 6 faces de notre cube (1 face avant, 1 face arrière, 1 face à gauche, 1 face à droite, 1 dessus, 1 dessous).

<div class="cube">
  <div>
    <div>Image 2</div>
    <div>Image 3</div>
    <div>Image 4</div>
    <div>Image 5</div>
    <div>Image 6</div>
    <div>Image 1</div>
  </div>
</div>

Voilà ce que cela donne :

Image 2
Image 3
Image 4
Image 5
Image 6
Image 1

Pour définir notre espace de travail,
nous écrivons dans notre fichier css :

.cube{
  padding: 20px; // marge interne de 20px autour de notre espace de travail.
  border: solid 1px red; // bordure trait plein rouge de 1px autour de notre espace de travail.
  width: 200px; // largeur du cube lui-même.
  height: 200px;// hauteur du cube.
  text-align: center;// centrage du cube dans notre espace de travail.
  display: inline-block;// definition du type de contenu dans notre espace de travail.
}

Nous allons maintenant placer les images dans notre cube,
et pour cela, nous écrivons dans le fichier :

<div class="cube">
  <div>
    <div><img
src="images/tutos/cube3d/img002.jpg" /></div>
    <div><img
src="images/tutos/cube3d/img003.jpg" /></div>
    <div><img
src="images/tutos/cube3d/img004.jpg" /></div>
    <div><img
src="images/tutos/cube3d/img005.jpg" /></div>
    <div><img
src="images/tutos/cube3d/img006.jpg" /></div>
    <div><img
src="images/tutos/cube3d/img001.jpg" /></div>
  </div>
</div>

   Le résultat ci-contre, à gauche, présente les photos les unes sous les autres,
   il nous faut donc créer une classe pour les retrouver toutes empilées
   dans le volume de notre espace de travail "cube2".

Figure 03

Pour cela, nous créons un css spécial ".volume" pour le placement des images,
qui s'écrit comme ceci :

.volume
 {

  overflow: hidden;
  position: absolute;
  border: 1px solid #888;
  opacity: 1;
 }

Et dans la page php on transforme les lignes comme ceci :

<div class="cube">
 <div>
  <div
class="volume"><img src="images/tutos/cube3d/img002.jpg" /></div>
  <div
class="volume"><img src="images/tutos/cube3d/img003.jpg" /></div>
  <div
class="volume"><img src="images/tutos/cube3d/img004.jpg" /></div>
  <div
class="volume"><img src="images/tutos/cube3d/img005.jpg" /></div>
  <div
class="volume"><img src="images/tutos/cube3d/img006.jpg" /></div>
  <div
class="volume"><img src="images/tutos/cube3d/img001.jpg" /></div>
 </div>
</div>

Nous obtenons le résultat figure 03 où on ne voit que la première image, puisqu'elles sont empilées.

On figure le plan de votre écran (votre image) par des axes "x" horizontal et "y" vertical.
Pour avoir un volume en 3D, il nous faut donc un troisième axe "z" qui sera donc perpendiculaire à votre écran, et sur cet axe on va définir un point de fuite, de perspective.
Dans notre cas on prendra z = 1000px, donc sortant de l'écran vers votre œil.
Plus l'image sera proche de votre œil, plus elle sera grosse, donc agrandie.

Schéma de grandeur visible d'une image en fonction de la distance.

D'ailleurs, même simplement vues comme cela sur l'écran, on a bien l'impresson que l'image de 3 est plus petite que celle du milieu, et c'est un effet de trompe l'œil, la droite est un copier-coller de la gauche !

Nous ajoutons donc une ligne dans notre css classe .cube :

.cube{
  padding: 20px; // marge interne de 20px autour de notre espace de travail.
  border: solid 1px red; // bordure trait plein rouge de 1px autour de notre espace de travail.
  perspective: 1000px; // définit le point de fuite de la perspective.
  width: 200px; // largeur du cube lui-même.
  height: 200px;// hauteur du cube.
  text-align: center;// centrage du cube dans notre espace de travail.
  display: inline-block;// definition du type de contenu dans notre espace de travail.
}

Maintenant on va faire comme si notre cube était placé à plat sur l'écran mais enfoncé de moitié dans le sens épaisseur.

On aura donc la face avant parallèle au plan de l'écran, mais avancée de 100px, puisque notre cube fait 200px de côté.
Donc z=100px.

La face arrière sera reculée de 100px. Donc z = -100px.


 
 
Figure 04

Nous allons ajouter des classes dans nos lignes :

<div class="cube">
 <div
class="boite3d">
  <div
class="volume cote--gauche"><img src="images/tutos/cube3d/img002.jpg" /></div>
  <div
class="volume cote--droit"><img src="images/tutos/cube3d/img003.jpg" /></div>
  <div
class="volume cote--sup"><img src="images/tutos/cube3d/img004.jpg" /></div>
  <div
class="volume cote--inf"><img src="images/tutos/cube3d/img005.jpg" /></div>
  <div
class="volume cote--arriere"><img src="images/tutos/cube3d/img006.jpg" /></div>
  <div
class="volume cote--avant"><img src="images/tutos/cube3d/img001.jpg" /></div>
 </div>
</div>

Nous commençons par écrire la classe ".boite3d" qui va englober les 6 côtés.

.boite3d
 {
  display: inline-block;
  
  text-align: center;
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d; indique que les 6 images (enfants) seront placées dans un espace à 3 dimensions.
  transform: rotateX(-15deg) rotateY(15deg); donne à l'ensemble du cube une transformation par rotation de 15 degrés autour des axes "x" et "y". Cette transformation sera annulée ensuite par la transformation suivante faite par chaque face du cube.
 }

En plus de cette transformation de 15 degrés, nous lui donnerons par la suite une durée d'environ 1 seconde, ce qui simulera l'effet d'aller-retour que vous avez constaté sur le modèle de départ en page précédente - figure 1.

Occupons-nous maintenant de placer le code css pour chaque face dans le volume.

Dans notre feuille css, nous allons ajouter les lignes suivantes :

Nous avons mis un "display:none;" dans chaque classe. Ceci est provisoire et sert simplement à afficher ou non les côtés. Il suffit de neutraliser la ligne, comme effectué dans la classe ".cote--arriere", pour que chacune apparaisse dans la figure 4.

.cote--sup {
 display:none;
 width: 200px;
 height: 200px;
 -moz-transform: rotateX(90deg) translate3d(-100px, 0, 100px);
 -webkit-transform: rotateX(90deg) translate3d(-100px, 0, 100px);
 -o-perspectivetransform: rotateX(90deg) translate3d(-100px, 0, 100px);
 -ms-perspectivetransform: rotateX(90deg) translate3d(-100px, 0, 100px);
 transform: rotateX(90deg) translate3d(-100px, 0, 100px);
}

.cote--inf {
 /*display:none;*/
 width: 200px;
 height: 200px;
 transform: rotateX(-90deg) translate3d(-100px, 0, 100px);
A compléter comme ci-dessus.
}

.cote--gauche {
 /*display:none;*/
 width: 200px;
 height: 200px;
 left: 50%;
 margin-left: -100px;
 transform: rotateY(-90deg) translate3d(0, 0, 100px);
A compléter comme ci-dessus.
}

.cote--droit {
 /*display:none;*/
 width: 200px;
 height: 200px;
 left: 50%;
 margin-left: -100px;
 transform: rotateY(90deg) translate3d(0, 0, 100px);
A compléter comme ci-dessus.
}

.cote--arriere{
 /*display:none;*/
 width: 200px;
 height: 200px;
 transform: rotateY(180deg) translate3d(0, 0, 100px);
A compléter comme ci-dessus.
}

.cote--avant {
 display:none;
 width: 200px;
 height: 200px;
 transform: translate3d(0, 0, 100px);
A compléter comme ci-dessus.
}

Pour chaque face, nous avons défini une transformation par une rotation suivant l'axe (x) ou l'axe (y) et par une translation nulle en x ou y, mais de 100px en z par rapport au plan xy.

Nous laissons volontairement la face avant et la face supérieure invisibles, pour voir le positionnement relatif des autres faces.


 
Ci-dessus : le cube sans la face avant ni la supérieure.

Le carré rouge figure le plan xy

Notre axe z est un axe qui part du centre de ce carré rouge et vient vers notre œil jusqu'à un point situé à 1000px sur cet axe.

Comme en plus, nous avons indiqué dans la classe .boite3d une rotation de -15 degrés par rapport à l'axe "x" et une rotation de 15 degrés par rapport à l'axe "y", nous obtenons bien l'effet de perspective de notre cube.

Notre cube fini :

A Brisbane en Australie 2003
Nous deux
Naissance Alexandre
Nous deux
Naissance Quentin
Alexandre et Arthur

 

 
Un peu d'animation :

Dans le modèle en page précédente, vous avez vu en cliquant sur les vignettes que l'on peut faire tourner le cube. C'est d'ailleurs nécessaire si l'on veut pouvoir regarder toutes les faces.
Nous allons donc maintenant voir comment faire cette animation.

Ce que nous voulons, c'est passer d'une face à l'autre et pour cela faire pivoter le cube. Ce sera donc une "transition".

Nous reprenons notre classe css .boite3d et nous y ajoutons une ligne comme ceci :

.boite3d
 {
  display: inline-block;
  transition: all 0.85s cubic-bezier(0.175,0.885,0.320,1.275); //notre nouvelle commande pour la transition
  text-align: center;
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d; // indique que les 6 images (enfants) seront placées dans un espace à 3 dimensions.
  transform: rotateX(-15deg) rotateY(15deg); // donne à l'ensemble du cube une transformation par rotation de 15 degrés autour des axes "x" et "y". Cette transformation s'applique à l'ensemble des 6 faces, une fois que celles-ci ont été définies.
 }

Crédit Alsacréations.Explication succincte de cette "cubic-bezier" :

Le site "alsacréations" vous documentera plus longuement sur cette fonction. Le schéma ci-contre en est extrait.
Je vous mets une interprétation simple :

  1. Le premier terme "all" de la transition signifie qu'elle s'appliquera à toutes les propriétés du contenu de la classe ".boite3d".
  2. Le second terme "0.85s", exprimé en secondes, est le temps total que durera la transition.
  3. Le premier élément P0 entre-parenthèses "0.175" exprime une vitesse initiale de transition. Cette vitesse de transition va ensuite suivre la "courbe de Bézier" bleue foncée.
  4. Le deuxième élément P1 entre-parenthèses "0.885" sert a établir le début de la courbe.
  5. Les 3 et 4ème (P2 et P3) éléments entre-parenthèses "0.320" et "1.275" servent à déterminer la fin de la transformation et sa vitesse.

Les heureux "forts en math" pourront éventuellement se remémorer leurs cours sur les courbes de Bézier.

Crédit Lea Verou.En fait, le plus simple est encore d'aller sur le site de Lea Verou où il vous suffira de faire glisser les points rouge et bleu des 2 tangentes pour déterminer et retrouver les résultats que nous avons inscrits dans notre formule.

Si vous prenez le temps de lire la page Alsacréations indiquée plus haut, vous trouverez plein d'exemples pour cette fonction.

J'ai finalement pris la formule :
"transition: all 0.85s cubic-bezier(0.175,0.885,0.320,1.275);"
dont le résultat est un effet de rebond intéressant.

Comment voir toutes les faces alternativement :

Pour commencer, créer les 6 boutons imagettes de type "bouton radio (option)" et pour cela, nous écrivons :

<input type="radio" name="select-cote" id="cote--gauche" class="css-checkbox" >
<label for="cote--gauche" class="css-label"<img src="images/tutos/cube3d/img002.jpg" width="30px"></label>
<input type="radio" name="select-cote" id="cote--droit" class="css-checkbox" >
<label for="cote--droit" class="css-label"<img src="images/tutos/cube3d/img003.jpg" width="30px"></label>
<input type="radio" name="select-cote" id="cote--sup" class="css-checkbox" >
<label for="cote--sup" class="css-label"<img src="images/tutos/cube3d/img004.jpg" width="30px"></label>
<input type="radio" name="select-cote" id="cote--inf" class="css-checkbox" >
<label for="cote--inf" class="css-label"<img src="images/tutos/cube3d/img005.jpg" width="30px"></label>
<input type="radio" name="select-cote" id="cote--arriere" class="css-checkbox" >
<label for="cote--arriere" class="css-label"<img src="images/tutos/cube3d/img006.jpg" width="30px"></label>
<input type="radio" checked name="select-cote" id="cote--avant" class="css-checkbox" >
<label for="cote--avant" class="css-label"<img src="images/tutos/cube3d/img001.jpg" width="30px"></label>

Vous voyez là les commandes habituelles de choix type radio d'un formulaire.
Mais en fait nous n'allons pas recharger la page à chaque choix,
nous allons utiliser les propriétés "css" des classes "css-checkbox" et "css-label"
qui seront affectée directement aux "id" de chaque côté.

Créons maintenant les CSS qui vont avec les vignettes ci-dessus :

#cote--gauche:checked ~ .cube .boite3d {
 -moz-transform: rotateX(-15deg) rotateY(105deg) ;
 -webkit-transform: rotateX(-15deg) rotateY(105deg) ;
 -o-transform: rotateX(-15deg) rotateY(105deg) ;
 -ms-transform: rotateX(-15deg) rotateY(105deg) ;
 transform: rotateX(-15deg) rotateY(105deg) ;
}
 
#cote--droite:checked ~ .cube .boite3d {
 transform: rotateX(-15deg) rotateY(-75deg) ;
 ---- je vous laisse écrire la suite -moz-...
}
 
#cote--inf:checked ~ .cube .boite3d {
 transform: rotateX(75deg) rotateZ(-15deg);
 ----
}

#cote--sup:checked ~ .cube .boite3d {
 transform: rotateX(-105deg) rotateZ(15deg);
 ----
}

#cote--arriere:checked ~ .cube .boite3d {
 transform: rotateX(-15deg) rotateY(-165deg) ;
 ----
}
 
#cote--avant:checked ~ .cube .boite3d {
 transform: rotateX(-15deg) rotateY(15deg) ;
 ----
}

A Brisbane en Australie 2003
Nous deux
Naissance Alexandre
Nous deux
Naissance Quentin
Alexandre et Arthur

 
Figure 05

Je profite des lignes ci-dessus pour vous montrer les préfixes de commandes
que vous devrez développer pour rendre les navigateurs compatibles.
Vous devrez faire de même dans cette page pour les commandes suivantes :
"perspective" - "transform" - "transition" - "transform-style:" - "animation" - etc.
enfin les nouvelles commandes css intégrées dernièrement.

Nous voyons que les propriétés css de chaque id ci-dessus
auront pour effet de faire tourner le cube pour ramener la face indiquée vers l'avant.

Pour cela, il nous faut encore créer les propriétés css des boutons-vignettes "input", et des "label".
Voir ci-dessous :

input[type=radio].css-checkbox { display:none;}
input[type=radio].css-checkbox + label.css-label
{
padding-left:3px;
height:30px;
display:inline-block;
line-height:30px;
background-repeat:no-repeat;
background-position: 0 0;
font-size:30px;
vertical-align:middle;
cursor:pointer;
}
 
input[type=radio].css-checkbox:checked + label.css-label
{ background-position: 0 -20px;}

Et pour finir, nous reprenons notre fichier css ".volume" dans lequel nous allons apporter un peu de finition :

.volume {
 overflow: hidden;
 position: absolute;
 border: 1px solid #8b4513;
 Vos 4 lignes box-shadow en -moz-, -webkit-, -o-, -ms-.
 box-shadow: inset 0 0 60px rgba(139, 69, 19, 0.1), 0 0 50px rgba(139, 69, 19, 0.3);
 opacity: 1; }

Explications du box-shadow :

"Inset" désigne une onbre vers l'intérieur.
Le 1er "0" indique le déplacement horizontal.
Le 2ème "0" indique le déplacement vertical.
Le "60px" indique le rayon du flou pour l'ombrage.
La couleur est donnée en mode RGBA, entre parenthèses, les 3 premiers chiffres pour la couleur, le 4ème pour la transparence, de 0 transparent à 1 opaque.

Après la definition du inset, il y a de la même façon la définition de l'ombre externe.

Conclusion :

J'étais curieux de savoir comment faire un "cube de photos". Je me suis plongé dans les pages Internet et me suis lancé à le faire à ma façon. Je n'ai rien inventé, mais j'ai trouvé le moyen de le mettre en pratique et en essayant de vous l'expliquer, mon apprentissage s'est amélioré.

J'espère avoir réussi à vous en faire profiter !

Mais on peut encore continuer et dans quelques jours, j'essaierai d'autres applications, animations, tourniquet, jeu de cartes...

Animation :

La méthode c'est par ici Explications pour animer un cube 3D de photos