1min30 > Blog > Développement web > Donner un effet 3D sur vos images 2D en utilisant une carte de profondeur
2018
25/Oct

Donner un effet 3D sur vos images 2D en utilisant une carte de profondeur

En parcourant les sites internet créatifs des Awwwards je suis tombé sur un effet plutôt intrigant. C’était une image qui disposait de plusieurs calques qui se déplaçaient de manière à ce que l’image ait un effet de profondeur (un effet 3d) au déplacement de ma souris. J’ai donc tenté de retrouver l’effet qui était appliqué. Dans cet article nous allons voir comment donner cet aspect de profondeur à une image et nous allons la créer grâce à une librairie.

L’effet 3D grâce à une carte de profondeur

Nous pouvons facilement recréer cet effet 3d en convertissant notre image en svg et récupérer chacune des balises images pour leur appliquer une transformation en fonction de la position X et Y de la souris. Cependant j’ai remarqué que le site internet où j’avais observé cet effet utilisait un canvas dans le but d’afficher l’image. J’ai donc compris qu’il ne s’agissait pas de transformation css mais bien d’animation créée en JavaScript.

Pour créer cet effet, voyons d’abord comment fonctionnent les cartes de profondeur. Ces cartes ajoutent des informations de distance à une image 2d et n’utilisent que les nuances de noir. Plus le noir est foncé, plus l’objet en question est éloigné et de la même manière la couleur blanche signifie que l’objet en question est plus proche.

Voici une représentation d’une image à gauche avec sa carte de profondeur à droite.
effet 3d

Construisons la base


 
<!DOCTYPE html>
 
<html lang="fr">
 
<head>
 
<meta charset="UTF-8">
 
<meta name="viewport"content="width=device-width, initial-scale=1.0">
 
<meta http-equiv="X-UA-Compatible"content="ie=edge">
 
<link rel="stylesheet"href="css/style.css">
 
<title>Three.js Crash Course</title>
 
</head>
 
<body>
 
 
<div class="wrapper"></div>
 
 
<script src="js/pixi.js"></script>
 
<script src="js/app.js"></script>
 
</body>
 
</html>
 

Nous allons pour ce faire utiliser les fonctionnalités de la librairie Pixi.js que je vous invite à aller découvrir directement sur le site officiel.

Passons à la logique du code


const w = window.innerWidth
const h = window.innerHeight

const renderer = new PIXI.WebGLRenderer(w,h)
const wrap = document.querySelector('.wrap')
wrap.appendChild(renderer.view)

let stage = new PIXI.Container()
let container = new PIXI.Container()
let foreground = new PIXI.Container()

stage.addChild(container)
stage.addChild(foreground)

let f, fg

let mousex = w/2 
let mousey = h/2

let ploader = new PIXI.loaders.Loader()

On commence d’abord par déclarer quelques variables, en commençant par récupérer les dimensions de l’écran de l’utilisateur. Le renderer comme dans la librairie THREE.js dont je vous parlais dans un de mes précédents articles et enfin un loader qui va tout simplement permettre de charger les images dans le canvas.

Les variables f et fg sont déclarées en tant que variables globales et seront utilisées plus tard lors du traitement. La variable f est utilisée en tant que filtre. On prendra en fait le filtre de déplacement (displacementFilter) de la librairie PIXI.js et on lui appliquera un modèle (qui est ici notre carte de profondeur).
On passe ensuite à l’exécution et le cœur même du code :


function init() {
	
	console.log('init')
	
	ploader.add('fg', 'https://cdn.1min30.com/wp-content/uploads/2018/08/pasted-image-0-21.png')
  	ploader.add('depth', 'https://cdn.1min30.com/wp-content/uploads/2018/08/pasted-image-0-22.png')

  	ploader.once('complete', start)
  	ploader.load()
}

function start() {
	fg = new PIXI.Sprite(ploader.resources.fg.texture)
	foreground.addChild(fg)
	
	d = new PIXI.Sprite(ploader.resources.depth.texture)
	f = new PIXI.filters.DisplacementFilter(d, 0)
	
	fg.filters = [f]
	
	window.addEventListener('mousemove', e => {
		mousex = e.clientX
		mousey = e.clientY
	})
	
	animate()
}

function animate() {
	f.scale.x = (window.innerWidth/2 - mousex) / 80;
 	f.scale.y = (window.innerHeight/2 - mousey) / 80;
  	fg.addChild(d);
  	d.renderable=false;
   
  	renderer.render(stage);       
  	requestAnimationFrame(animate);
}

 

Nous avons ici trois fonctions :

  • init()
  • start()
  • animate()

La fonction init

Elle va charger les 2 images grâce au loader de la librairie PIXI.JS.
Une fois que les loaders auront fini leur travail, la librairie lancera la fonction d’après.

La fonction start

Cette fonction va se permettre de “painter” les images qui ont été chargées et les appliquer sur leurs conteneurs PIXI.js respectifs.
C’est ici qu’on applique le filtre de déplacement avec comme référence notre carte de profondeur qui va permettre d’appliquer un effet 3d à notre image.
Enfin on applique le filtre à l’image. Puis on écoute les mouvements de la souris et on change les valeurs des variables mousex et mousey.
Cette fonction appelle alors la fonction animate.

La fonction animate

Elle est déclenchée à chaque fois que les variables mousex et mousey sont modifiées. On applique alors une transformation sur l’échelle du filtre en fonction de la position de la souris.
Une fois que cela est fait on crée le rendu qui va créer cet effet 3d grâce à la fonction requestAnimationFrame.
Bien sûr une fois que ces fonction sont déclarées on n’oublie pas de lancer la fonction init() une fois.


init()

 

C’est tout ?

Oui, grâce à la librairie PIXI.js on a un rendu plutôt satisfaisant et avec très peu de lignes de code. Celle-ci se permet de faire le travail entre les 2 images qu’on lui donne et fait tous les calculs nécessaires pour effectuer les transformations sur l’image.

Voici le rendu :

Si cet article vous a plu je vous invite à télécharger notre livre blanc “Les 11 commandements d’un site qui convertit vos visiteurs en clients” et à contacter notre agence web.

Paartheepan Raveenthiran

Posté par

Je suis actuellement étudiant dans le domaine du multimédia et de l'internet et passionné par le mon

Paartheepan Raveenthiran

Contact Développement web :

Jérémie Dornbusch

jd@1min30.com
0785928777





Commenter

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.

Abonnez-vous à notre excellente newsletter

Hey ne partez pas si vite !

Contactez-nous
Do NOT follow this link or you will be banned from the site!