Blog / JavaScript

Confetti, fireworks et particles

Creez des effets speciaux festifs et memorables pour vos interfaces : confetti, feux d'artifice, neige, particules flottantes et etincelles en JavaScript pur.

Introduction

Les effets speciaux festifs comme les confetti, les feux d'artifice et les particules ajoutent une touche de magie a vos interfaces. Qu'il s'agisse de celebrer un achat, de feliciter un utilisateur ou simplement d'embellir une landing page, ces animations visuelles creent des moments memorables.

Dans ce tutoriel, nous allons explorer 5 effets speciaux differents en JavaScript pur : des confetti explosifs aux flocons de neige, en passant par les feux d'artifice Canvas. Chaque exemple est accompagne du code complet, pret a copier dans votre projet.

💡
Bon a savoir

Tous les effets de cet article utilisent du JavaScript pur, sans aucune librairie externe. Ils combinent les approches DOM (elements HTML animes) et Canvas (dessin pixel par pixel) selon les besoins.

1. Confetti Explosion

L'effet confetti est parfait pour celebrer les actions reussies : validation de formulaire, achat termine, objectif atteint. On cree des elements DOM colores avec des animations CSS aleatoires.

Le principe

On genere dynamiquement des dizaines d'elements <div> positionnes en absolu, chacun avec une couleur aleatoire, une direction et une vitesse de chute unique. L'animation CSS @keyframes gere la gravite et la rotation.

confetti.js
function createConfetti() {
  const container = document.getElementById('confettiBox');
  const colors = [
    '#6366f1', '#8b5cf6', '#d946ef',
    '#f59e0b', '#10b981', '#ef4444'
  ];

  for (let i = 0; i < 50; i++) {
    const confetti = document.createElement('div');
    const color = colors[Math.floor(Math.random() * colors.length)];
    const size = Math.random() * 8 + 6;
    const left = Math.random() * 100;
    const delay = Math.random() * 0.5;
    const duration = 2 + Math.random() * 2;

    confetti.style.cssText = `
      position: absolute;
      width: ${size}px;
      height: ${size}px;
      background: ${color};
      left: ${left}%;
      top: 0;
      border-radius: ${Math.random() > 0.5 ? '50%' : '2px'};
      animation: confettiFall ${duration}s ease-out
                 ${delay}s forwards;
    `;

    container.appendChild(confetti);
    setTimeout(() => confetti.remove(), 4500);
  }
}

L'animation CSS associee

confetti-keyframes.css
@keyframes confettiFall {
  0% {
    transform: translateY(0) rotate(0);
    opacity: 1;
  }
  100% {
    transform: translateY(300px) rotate(720deg);
    opacity: 0;
  }
}
💡
Astuce

Utilisez border-radius: 50% pour des confettis ronds et border-radius: 2px pour des rectangles. Alterner les formes rend l'effet plus naturel.

2. Particules flottantes

Les particules flottantes creent une ambiance immersive pour vos arriere-plans. Cet effet utilise l'API Canvas pour dessiner et animer des dizaines de particules avec des connexions entre elles.

Le principe

On initialise un tableau de particules avec des positions et vitesses aleatoires. A chaque frame, on deplace les particules, on les dessine et on trace des lignes entre celles qui sont proches les unes des autres.

particles.js
function initParticles(canvasId) {
  const canvas = document.getElementById(canvasId);
  const ctx = canvas.getContext('2d');
  canvas.width = canvas.offsetWidth;
  canvas.height = canvas.offsetHeight;

  const particles = [];
  const count = 40;
  const maxDist = 120;

  for (let i = 0; i < count; i++) {
    particles.push({
      x: Math.random() * canvas.width,
      y: Math.random() * canvas.height,
      vx: (Math.random() - 0.5) * 0.8,
      vy: (Math.random() - 0.5) * 0.8,
      r: Math.random() * 2 + 1
    });
  }

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

    particles.forEach(p => {
      p.x += p.vx;
      p.y += p.vy;
      if (p.x < 0 || p.x > canvas.width) p.vx *= -1;
      if (p.y < 0 || p.y > canvas.height) p.vy *= -1;

      ctx.beginPath();
      ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
      ctx.fillStyle = 'rgba(99, 102, 241, 0.6)';
      ctx.fill();
    });

    // Lignes entre particules proches
    for (let i = 0; i < count; i++) {
      for (let j = i + 1; j < count; j++) {
        const dx = particles[i].x - particles[j].x;
        const dy = particles[i].y - particles[j].y;
        const dist = Math.sqrt(dx * dx + dy * dy);
        if (dist < maxDist) {
          ctx.strokeStyle =
            `rgba(99,102,241,${1 - dist/maxDist})`;
          ctx.lineWidth = 0.5;
          ctx.beginPath();
          ctx.moveTo(particles[i].x, particles[i].y);
          ctx.lineTo(particles[j].x, particles[j].y);
          ctx.stroke();
        }
      }
    }

    requestAnimationFrame(animate);
  }
  animate();
}
🔗
Lignes de connexion

Les lignes entre particules proches creent un effet de reseau (mesh). L'opacite diminue avec la distance pour un rendu naturel. Ajustez maxDist pour controler la densite du reseau.

3. Sparkles / Etincelles

Les etincelles (sparkles) sont des petites particules lumineuses qui suivent le curseur de la souris ou apparaissent autour d'un element au survol. C'est un effet elegant pour attirer l'attention sur un CTA ou un element premium.

Trail de curseur

On ecoute les mouvements de souris et on cree des mini-elements lumineux a chaque deplacement. Chaque etincelle grossit puis disparait en fondu.

sparkles.js
function initSparkles() {
  document.addEventListener('mousemove', (e) => {
    const sparkle = document.createElement('div');
    const size = Math.random() * 6 + 4;
    const colors = ['#fbbf24', '#f59e0b', '#fff'];
    const color = colors[
      Math.floor(Math.random() * colors.length)
    ];

    sparkle.style.cssText = `
      position: fixed;
      pointer-events: none;
      width: ${size}px;
      height: ${size}px;
      background: ${color};
      border-radius: 50%;
      left: ${e.clientX}px;
      top: ${e.clientY}px;
      box-shadow: 0 0 6px ${color};
      animation: sparkleFade 0.6s ease-out forwards;
      z-index: 9999;
    `;

    document.body.appendChild(sparkle);
    setTimeout(() => sparkle.remove(), 600);
  });
}

// Keyframes a ajouter en CSS :
// @keyframes sparkleFade {
//   0%   { transform: scale(0); opacity: 1; }
//   50%  { transform: scale(1); opacity: 0.8; }
//   100% { transform: scale(0); opacity: 0; }
// }
⚠️
Attention a la performance

Creer un element DOM a chaque evenement mousemove peut vite devenir couteux. Utilisez un throttle (par exemple un appel tous les 50ms) pour limiter le nombre d'etincelles creees simultanement.

4. Neige qui tombe

L'effet neige est ideal pour les themes hivernaux, les pages de Noel ou tout simplement pour une ambiance douce et apaisante. On utilise Canvas pour dessiner des flocons qui tombent avec un leger mouvement horizontal.

Implementation Canvas

Chaque flocon a une taille, une vitesse et un decalage horizontal aleatoires. Quand un flocon atteint le bas du canvas, il est replace en haut pour un effet continu.

snow.js
function initSnow(canvasId) {
  const canvas = document.getElementById(canvasId);
  const ctx = canvas.getContext('2d');
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;

  const flakes = [];
  const count = 100;

  for (let i = 0; i < count; i++) {
    flakes.push({
      x: Math.random() * canvas.width,
      y: Math.random() * canvas.height,
      r: Math.random() * 3 + 1,
      speed: Math.random() * 1 + 0.5,
      wind: Math.random() * 0.5 - 0.25,
      opacity: Math.random() * 0.5 + 0.3
    });
  }

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

    flakes.forEach(f => {
      f.y += f.speed;
      f.x += f.wind;

      // Replacer en haut si sorti
      if (f.y > canvas.height) {
        f.y = -5;
        f.x = Math.random() * canvas.width;
      }

      ctx.beginPath();
      ctx.arc(f.x, f.y, f.r, 0, Math.PI * 2);
      ctx.fillStyle =
        `rgba(255, 255, 255, ${f.opacity})`;
      ctx.fill();
    });

    requestAnimationFrame(animate);
  }
  animate();
}

Personnalisation

  • Nombre de flocons : ajustez count (50 pour subtil, 200 pour tempete)
  • Vitesse de chute : modifiez le multiplicateur dans speed
  • Vent : changez la plage de wind pour un mouvement lateral plus ou moins prononce
  • Opacite : variez pour creer un effet de profondeur (flocons proches vs lointains)

5. Feux d'artifice

L'effet le plus spectaculaire : un feu d'artifice qui explose depuis un point central avec des particules colorees qui retombent en arc sous l'effet de la gravite. On utilise Canvas avec une simulation physique simplifiee.

La physique simplifiee

Chaque particule a une velocite initiale dans une direction aleatoire. A chaque frame, on applique une gravite qui tire les particules vers le bas, creant l'arc naturel d'un feu d'artifice.

fireworks.js
function initFireworks(canvasId) {
  const canvas = document.getElementById(canvasId);
  const ctx = canvas.getContext('2d');
  canvas.width = canvas.offsetWidth;
  canvas.height = canvas.offsetHeight;

  let particles = [];
  const gravity = 0.03;

  function explode(x, y) {
    const count = 60;
    const hue = Math.random() * 360;

    for (let i = 0; i < count; i++) {
      const angle = (Math.PI * 2 / count) * i;
      const speed = Math.random() * 3 + 1;

      particles.push({
        x, y,
        vx: Math.cos(angle) * speed,
        vy: Math.sin(angle) * speed,
        life: 1,
        decay: Math.random() * 0.01 + 0.005,
        color: `hsl(${hue + Math.random()*30}, 100%, 60%)`
      });
    }
  }

  function animate() {
    // Fond semi-transparent pour trainee
    ctx.fillStyle = 'rgba(10, 10, 15, 0.15)';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    particles.forEach(p => {
      p.x += p.vx;
      p.y += p.vy;
      p.vy += gravity;  // Gravite
      p.life -= p.decay;

      ctx.beginPath();
      ctx.arc(p.x, p.y, 2, 0, Math.PI * 2);
      ctx.globalAlpha = p.life;
      ctx.fillStyle = p.color;
      ctx.fill();
    });

    ctx.globalAlpha = 1;
    // Nettoyer les particules mortes
    particles = particles.filter(p => p.life > 0);

    requestAnimationFrame(animate);
  }

  // Clic pour lancer un feu d'artifice
  canvas.addEventListener('click', (e) => {
    const rect = canvas.getBoundingClientRect();
    explode(e.clientX - rect.left, e.clientY - rect.top);
  });

  animate();
}
💡
Effet de trainee

Au lieu d'effacer completement le canvas avec clearRect, on dessine un rectangle semi-transparent (rgba(10, 10, 15, 0.15)) a chaque frame. Cela laisse une trainee lumineuse derriere chaque particule, un effet tres realiste pour les feux d'artifice.

Bonnes pratiques

Avant de deployer ces effets en production, voici quelques recommandations essentielles pour garantir une experience fluide :

Performance

  • Utilisez toujours requestAnimationFrame au lieu de setInterval pour les animations continues. Le navigateur optimise le rendu et met en pause l'animation quand l'onglet est inactif.
  • Limitez le nombre de particules : 50 a 100 suffisent pour un bel effet. Au-dela de 200, les performances chutent sur mobile.
  • Preferez Canvas au DOM pour les grandes quantites de particules. Manipuler des centaines d'elements DOM est bien plus couteux que de dessiner sur un canvas.

Nettoyage et memoire

  • Supprimez les particules mortes avec filter() ou gerez un pool de particules reutilisables pour eviter les fuites memoire.
  • Nettoyez les listeners quand le composant est demonte (important en SPA avec React, Vue, etc.).
  • Utilisez cancelAnimationFrame pour stopper les animations quand elles ne sont plus visibles.

Mobile et accessibilite

responsive-check.js
// Reduire les particules sur mobile
const isMobile = window.innerWidth < 768;
const particleCount = isMobile ? 25 : 60;

// Respecter prefers-reduced-motion
const prefersReduced = window
  .matchMedia('(prefers-reduced-motion: reduce)')
  .matches;

if (!prefersReduced) {
  initParticles('myCanvas', particleCount);
}
⚠️
Accessibilite

Verifiez toujours prefers-reduced-motion avant de lancer des animations automatiques. Certains utilisateurs souffrent de troubles vestibulaires et les animations peuvent provoquer des nausees ou des vertiges.

Conclusion

Les effets speciaux festifs sont un excellent moyen de rendre vos interfaces plus vivantes et memorables. Que ce soit pour celebrer une action utilisateur avec des confettis, creer une ambiance hivernale avec de la neige ou impressionner avec un feu d'artifice, JavaScript offre toute la puissance necessaire.

L'approche DOM (confetti, sparkles) est ideale pour des effets ponctuels avec peu d'elements. L'approche Canvas (particules, neige, fireworks) est preferable quand le nombre d'elements augmente. Dans tous les cas, pensez toujours a la performance, au nettoyage memoire et a l'accessibilite.

🎨
Allez plus loin

Retrouvez des effets speciaux prets a l'emploi dans notre bibliotheque d'effets, avec code copiable en un clic et personnalisation en temps reel.