Animation javascript dans page web

Arbres fractals en JavaScript

Une progression en 4 étapes : de la simple branche jusqu’à l’arbre fractal élégant, animé, coloré et “propre pour la scène”.
Public : 6 → 18 ans + bonus pour devs curieux

1) Étape 1 – Une seule branche

Objectif : comprendre le principe de base : une ligne sur un canvas. C’est la “colonne vertébrale” de l’arbre.

  • On crée un canvas de 400×400 pixels.
  • On trace une branche verticale en utilisant moveTo et lineTo.
  • C’est le tronc de l’arbre.
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <title>Branche simple</title>
  <style>
    body {
      margin: 0;
      background: #f4f4f4;
    }
    canvas {
      display: block;
      margin: auto;
      background: white;
      border: 1px solid #ccc;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="400" height="400"></canvas>

  <script>
    const ctx = document.getElementById('canvas').getContext('2d');

    ctx.strokeStyle = 'green';
    ctx.lineWidth   = 4;

    ctx.beginPath();
    ctx.moveTo(200, 400);  // pied du tronc
    ctx.lineTo(200, 300);  // haut du tronc
    ctx.stroke();
  </script>
</body>
</html>

2) Étape 2 – Premier arbre fractal (statique)

Objectif : découvrir la récursivité. Une branche dessine deux sous-branches, qui dessinent elles-mêmes deux sous-branches, etc. On obtient un arbre fractal.

  • Fonction drawBranch qui s’appelle elle-même.
  • À chaque niveau : longueur ×0,7 et deux angles (gauche / droite).
  • depth contrôle la profondeur (nombre de niveaux).
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <title>Arbre Fractal Statique</title>
  <style>
    body {
      margin: 0;
      background: #e0f7fa;
    }
    canvas {
      display: block;
      margin: auto;
      background: white;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="600" height="600"></canvas>

  <script>
    const canvas = document.getElementById('canvas');
    const ctx    = canvas.getContext('2d');

    function drawBranch(x, y, len, angle, depth) {
      if (depth === 0) return;

      const x2 = x + len * Math.cos(angle);
      const y2 = y + len * Math.sin(angle);

      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x2, y2);
      ctx.stroke();

      // Deux sous-branches
      drawBranch(x2, y2, len * 0.7, angle - 0.5, depth - 1);
      drawBranch(x2, y2, len * 0.7, angle + 0.5, depth - 1);
    }

    ctx.strokeStyle = 'brown';
    ctx.lineWidth   = 2;

    // Point de départ : milieu en bas, qui monte
    drawBranch(300, 600, 100, -Math.PI / 2, 6);
  </script>
</body>
</html>

3) Étape 3 – Arbre fractal animé (respirant)

Objectif : rendre l’arbre vivant. On garde le principe récursif, mais on fait varier l’angle de séparation avec le temps (Math.sin(t)) pour que l’arbre “respire”.

  • Canvas plein écran, qui se redimensionne automatiquement.
  • Variable t qui augmente à chaque frame.
  • spread = 0.5 + 0.2 * Math.sin(t) : l’arbre s’ouvre / se referme.
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <title>Arbre Fractal Animé</title>
  <style>
    html, body {
      margin: 0;
      overflow: hidden;
      background: #000;
    }
    canvas {
      display: block;
    }
  </style>
</head>
<body>
  <canvas id="canvas"></canvas>

  <script>
    const canvas = document.getElementById('canvas');
    const ctx    = canvas.getContext('2d');

    function resize() {
      canvas.width  = window.innerWidth;
      canvas.height = window.innerHeight;
    }
    window.addEventListener('resize', resize);
    resize();

    let t = 0; // temps

    function drawBranch(x, y, len, angle, depth) {
      if (depth === 0) return;

      const x2 = x + len * Math.cos(angle);
      const y2 = y + len * Math.sin(angle);

      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x2, y2);
      ctx.stroke();

      const spread = 0.5 + 0.2 * Math.sin(t);

      drawBranch(x2, y2, len * 0.7, angle - spread, depth - 1);
      drawBranch(x2, y2, len * 0.7, angle + spread, depth - 1);
    }

    function animate() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      ctx.strokeStyle = 'lightgreen';
      ctx.lineWidth   = 2;

      drawBranch(
        canvas.width  / 2,
        canvas.height,
        canvas.height / 5,
        -Math.PI / 2,
        8
      );

      t += 0.02;
      requestAnimationFrame(animate);
    }

    animate();
  </script>
</body>
</html>

4) Étape 4 – Arbre fractal élégant (trails + couleurs HSL)

Objectif : transformer la démo en pièce artistique :

  • Fond qui ne s’efface pas totalement → traînées (afterglow).
  • Couleur de l’arbre en HSL qui tourne dans le cercle chromatique.
  • Arbre qui ondule doucement, hypnotique.
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <title>Arbre Fractal Élégant</title>
  <style>
    html, body {
      margin: 0;
      background: black;
      overflow: hidden;
    }
    canvas {
      display: block;
    }
  </style>
</head>
<body>
  <canvas id="canvas"></canvas>

  <script>
    const canvas = document.getElementById('canvas');
    const ctx    = canvas.getContext('2d');

    let width, height;

    function resize() {
      width  = canvas.width  = window.innerWidth;
      height = canvas.height = window.innerHeight;
    }
    window.addEventListener('resize', resize);
    resize();

    let angleOffset = 0;

    function drawBranch(x, y, len, angle, depth) {
      if (depth === 0) return;

      const x2 = x + len * Math.cos(angle);
      const y2 = y + len * Math.sin(angle);

      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x2, y2);
      ctx.stroke();

      const nextLen = len * 0.7;
      const spread  = 0.5 + 0.2 * Math.sin(angleOffset);

      drawBranch(x2, y2, nextLen, angle - spread, depth - 1);
      drawBranch(x2, y2, nextLen, angle + spread, depth - 1);
    }

    function animate() {
      // Voile noir transparent → traînées
      ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
      ctx.fillRect(0, 0, width, height);

      // Couleur qui tourne en HSL
      ctx.strokeStyle = `hsl(${(angleOffset * 60) % 360}, 100%, 70%)`;
      ctx.lineWidth   = 2;

      drawBranch(
        width  / 2,
        height,
        height / 4,
        -Math.PI / 2,
        9
      );

      angleOffset += 0.01;
      requestAnimationFrame(animate);
    }

    animate();
  </script>
</body>
</html>

QCM – As-tu vraiment compris les arbres fractals ?

Coche une réponse par question, puis clique sur “Vérifier”.

  1. Dans la fonction drawBranch(x, y, len, angle, depth), à quoi sert le paramètre depth ?


  2. Que représente la ligne : drawBranch(x2, y2, len * 0.7, angle - 0.5, depth - 1); ?


  3. Dans l’étape 3, à quoi sert la variable t ?


  4. Pourquoi, dans l’étape 4, n’efface-t-on pas complètement le canvas à chaque frame ?


  5. Que signifie la notation hsl(hue, 100%, 70%) utilisée pour les couleurs ?


Idées d’exercices pour les élèves (et les profs en manque d’inspi)

  • 6–10 ans : changer la couleur de l’arbre, l’épaisseur des branches, la longueur de départ.
  • 10–13 ans : tester plusieurs facteurs (0.5, 0.6, 0.8) au lieu de 0.7, ou modifier les angles.
  • Collège–Lycée : ajouter un contrôle au clavier pour augmenter/diminuer depth en temps réel.
  • Avancés : faire pousser 2 arbres en même temps (gauche / droite), ou faire changer la couleur selon la profondeur.
  • Bonus dev : associer la vitesse d’animation à la position de la souris ou au son (avec Web Audio API).

Commentaires

Posts les plus consultés de ce blog

Basthon.fr

mBot2 - programmation mBlock/python

Mario Kart 2D