Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 11

Navigation interactive avec OrbitControls

Recommended resources

Bonjour ! Dans la leçon précédente, nous avons donné vie à notre scène en créant une boucle d'animation qui fait tourner notre cube. Cependant, nous sommes toujours des spectateurs passifs, observant la scène depuis un point de vue fixe. Il est temps de prendre les commandes.

Introduction

L'objectif de cette leçon est de rendre notre scène interactive. Pour cela, vous allez apprendre à intégrer des contrôles de caméra OrbitControls pour permettre une navigation interactive. Cet outil, fourni avec Three.js, est un moyen extrêmement efficace de permettre à l'utilisateur de se déplacer dans la scène en utilisant la souris ou les gestes tactiles pour orbiter, zoomer et se déplacer.

À la fin de cette leçon, vous pourrez explorer librement votre scène 3D, une étape cruciale pour créer des expériences immersives comme des configurateurs de produits ou des visites virtuelles.

OrbitControls in Three.js: Camera Perspectives
Cette image illustre comment les `OrbitControls` permettent à la caméra de "tourner" (orbiter) autour d'un point central, offrant ainsi différentes perspectives de la scène.

1. Qu'est-ce que OrbitControls ?

OrbitControls n'est pas inclus dans le cœur de la bibliothèque Three.js, mais il fait partie des "extras" très utiles fournis dans le dossier examples. Il encapsule toute la logique complexe nécessaire pour :

  • Orbiter : Tourner autour d'un point central (par défaut, l'origine de la scène) en cliquant et en faisant glisser le bouton gauche de la souris.
  • Zoomer : Se rapprocher ou s'éloigner en utilisant la molette de la souris.
  • Faire un panoramique (Pan) : Déplacer la caméra latéralement en cliquant et en faisant glisser le bouton droit de la souris.

L'intégrer nous évite de devoir réinventer la roue en codant manuellement la gestion des événements de la souris, les calculs de position et les rotations de la caméra.


2. Mettre en place les OrbitControls

L'ajout des contrôles se fait en trois étapes simples : importer la classe, l'instancier, et la mettre à jour dans notre boucle d'animation.

L'article de blog ci-dessous présente un extrait de code très concis qui résume parfaitement ces étapes.

Tutoriel Three.js : Interaction et contrôles

Lisez cette courte section pour voir comment implémenter les contrôles. Elle utilise la syntaxe d'importation de modules ES6 que nous utilisons déjà dans notre projet Vite.

Concentrez-vous sur la section 8, 'Interaction et contrôles'. Observez les trois lignes de code principales : l'importation de OrbitControls, sa création (new OrbitControls(...)), et l'appel à controls.update() dans la boucle animate.

Analysons ces étapes en détail.

Étape 1 : Importer OrbitControls

Comme OrbitControls est un module additionnel, nous devons l'importer explicitement en haut de notre fichier main.js.

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

Étape 2 : Instancier les contrôles

Après avoir initialisé la caméra et le renderer, nous pouvons créer une instance des contrôles.

const controls = new OrbitControls(camera, renderer.domElement);

Cette ligne de code a besoin de deux arguments essentiels :

  1. camera : La caméra que les contrôles doivent manipuler.
  2. renderer.domElement : L'élément <canvas> sur lequel les contrôles doivent écouter les événements de la souris (clics, mouvements) et tactiles.

Étape 3 : Mettre à jour dans la boucle d'animation

Pour que les contrôles fonctionnent de manière fluide, notamment si l'on active des effets comme l'amortissement (damping), il est crucial de les mettre à jour à chaque image.

Pour cela, on active d'abord l'amortissement, qui donne une sensation d'inertie et de poids à la caméra, la rendant plus naturelle.

controls.enableDamping = true;

Ensuite, nous devons appeler controls.update() à l'intérieur de notre fonction animate. Cette fonction applique les changements progressifs de l'amortissement à la position de la caméra à chaque frame.

function animate() {
    requestAnimationFrame(animate);

    // Mettre à jour les contrôles
    controls.update();

    // ... la rotation de notre cube ...
    cube.rotation.y += 0.01;
    cube.rotation.x += 0.005;

    // Rendre la scène
    renderer.render(scene, camera);
}

Pourquoi est-ce nécessaire ? Sans controls.update() dans la boucle, les contrôles fonctionneraient, mais l'effet d'amortissement serait ignoré. La caméra s'arrêterait net dès que vous relâchez la souris. L'appel update() garantit que le mouvement se poursuit et ralentit doucement sur plusieurs frames.


3. Code mis à jour et démonstration

Voici à quoi ressemble notre fichier main.js complet avec les OrbitControls.

import * as THREE from 'three';
// 1. Importer OrbitControls
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

// Le Moteur de Rendu (Renderer)
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// La Scène
const scene = new THREE.Scene();

// La Caméra
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
);
camera.position.z = 5;

// Création de notre objet
const geometry = new THREE.BoxGeometry(1.5, 1.5, 1.5);
const material = new THREE.MeshBasicMaterial({ color: 0x0095dd });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 2. Instancier les contrôles
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // Ajoute de l'inertie au mouvement
controls.dampingFactor = 0.05; // Force de l'amortissement

// La boucle d'animation
function animate() {
    requestAnimationFrame(animate);

    // 3. Mettre à jour les contrôles à chaque frame
    controls.update();

    // On garde notre animation de cube
    cube.rotation.y += 0.01;
    cube.rotation.x += 0.005;

    // Rendre la scène
    renderer.render(scene, camera);
}

// Démarrer la boucle
animate();

// Gestion du redimensionnement
window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
});

Lancez votre projet. Vous devriez maintenant pouvoir tourner autour du cube, zoomer et vous déplacer !


4. Personnaliser le comportement des contrôles

OrbitControls est très configurable. Voici quelques-unes des propriétés les plus utiles pour affiner l'expérience utilisateur.

  • Changer la cible de l'orbite : Par défaut, la caméra tourne autour de l'origine (0, 0, 0). Pour la faire tourner autour d'un autre point (par exemple, un objet qui n'est pas au centre), utilisez :

    controls.target.set(x, y, z);
    
  • Limiter le zoom : Pour éviter que l'utilisateur ne zoome trop près ou trop loin :

    controls.minDistance = 2; // Zoom minimum
    controls.maxDistance = 10; // Zoom maximum
    
  • Restreindre l'angle vertical : Très utile pour empêcher l'utilisateur de passer sous le "sol" de la scène. L'angle est en radians (Math.PI = 180°).

    // Empêche de regarder plus haut que la verticale (0 = zénith)
    controls.minPolarAngle = 0; 
    
    // Empêche de regarder plus bas que l'horizon (Math.PI / 2 = 90°)
    controls.maxPolarAngle = Math.PI / 2;
    

    L'article suivant mentionne cette propriété ainsi que la rotation automatique, une autre option intéressante.

Tutoriel Three.js, ajout de paramètres de contrôles

Cette section d'un tutoriel de Florian Gouloubi montre comment utiliser maxPolarAngle pour contraindre la caméra. C'est un exemple pratique de personnalisation.

Lisez la section 8, 'Ajout de paramètres de contrôles et rotation automatique'. Notez l'utilisation de maxPolarAngle et minPolarAngle pour limiter le mouvement de la caméra.

  • Désactiver le panoramique ou la rotation :
    controls.enablePan = false;
    controls.enableRotate = false;
    
  • Rotation automatique : Pour faire tourner la caméra automatiquement autour de la cible.
    controls.autoRotate = true;
    controls.autoRotateSpeed = 0.5; // Vitesse de rotation
    
    N'oubliez pas que si autoRotate est activé, controls.update() doit être appelé dans la boucle d'animation.

La vidéo suivante (en anglais) est une excellente démonstration visuelle de la mise en place et de la configuration de plusieurs de ces propriétés.

Three.JS Orbit Controls: Zoom, Pan, Rotate [Checkers 1]

Cette vidéo de SyntaxByte (en anglais) montre pas à pas comment ajouter et configurer les OrbitControls. Même si vous ne suivez pas le code, observer les effets visuels de chaque modification de paramètre peut être très instructif.

Regardez ces passages pour voir en action ce que nous avons appris : 08:18 - 11:19 : Implémentation de base. 12:27 - 14:32 : Définition de la cible (target). 14:48 - 15:21 : Désactivation du panoramique (enablePan). 15:24 - 16:34 : Limitation de l'angle polaire (maxPolarAngle). 17:00 - 19:01 : Activation de l'amortissement (enableDamping).


Exercice

Mettez en pratique ce que vous venez d'apprendre. Modifiez votre code pour :

  1. Limiter le zoom pour que la caméra reste toujours entre 3 et 8 unités de distance du centre.
  2. Empêcher l'utilisateur de voir le cube par en dessous. La caméra ne doit pas pouvoir passer sous le plan horizontal (XY).

Conclusion

Félicitations ! Vous avez ajouté une couche d'interactivité essentielle à votre scène 3D. Cette compétence est fondamentale et sera réutilisée dans la quasi-totalité de vos futurs projets.

Points clés à retenir :

  • OrbitControls est la solution standard pour ajouter rapidement une navigation par caméra (orbite, zoom, panoramique).
  • Il s'implémente en trois temps : importer, instancier (avec la caméra et le canvas), et mettre à jour dans la boucle d'animation (surtout si enableDamping est actif).
  • De nombreuses propriétés (maxDistance, maxPolarAngle, target, etc.) permettent de personnaliser finement le comportement pour l'adapter aux besoins de votre application.

Aperçu de la prochaine leçon :
Maintenant que nous pouvons nous déplacer librement, nous allons avoir besoin d'outils plus précis pour manipuler les objets dans notre scène. Placer un objet aux coordonnées (1.5, 2, -3) est une chose, mais comment calculer la distance jusqu'à un autre objet ? Ou le déplacer dans une direction spécifique ? Dans la prochaine leçon, nous aborderons la classe Vector3, le couteau suisse mathématique de Three.js pour gérer les positions, les échelles et les directions dans l'espace 3D.