Atmosphère✨ Premium

Fire Effect

Particules de feu 2D canvas — dégradé jaune→orange→rouge piloté par la durée de vie, traînée fumée via fond semi-transparent, 3 spawns par frame depuis la base.

JSCanvasFire

Vous aurez accès à la démo interactive avec un compte gratuit.

Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Atmosphère comprend 57 effets, dont 10 gratuits. Découvrir la catégorie →

3 exemples d'usage

Hero / Landing — Page de lancement « offres brûlantes » — Fire Effect exemple 1

① Hero / Landing — Page de lancement « offres brûlantes »

QuandLancement d'une vente flash, d'une offre limitée ou d'un compte à rebours promotionnel où l'urgence visuelle doit s'imposer dès le premier regard.
PourquoiLa colonne de feu centrale crée une ancre visuelle forte et oriente naturellement le regard vers le titre et le CTA, sans recourir à une image lourde — zéro requête réseau.
RéglagesValeurs par défaut : 3 spawns/frame, spread ±20 px, taille 3–9 px. Pour une flamme plus dense sur grand écran, montez le spawn à 5–6 en éditant la boucle for (let n = 0; n < 3; n++).
Écran de résultat gamifié — Accomplissement fitness ou apprentissage — Fire Effect exemple 2

② Écran de résultat gamifié — Accomplissement fitness ou apprentissage

QuandAfficher un score final, un record personnel ou un palier débloqué dans une app de sport ou d'apprentissage — les flammes ancrent visuellement la sensation de victoire.
PourquoiLe feu monte sur toute la hauteur de l'écran depuis le bas, renforçant l'émotion d'accomplissement par la métaphore chaleur / énergie / ascension — lisible sans un mot supplémentaire.
RéglagesSpawn à 5/frame (for (let n = 0; n < 3; n++)n < 5) ; spread élargi à ±40 px (4080) pour une nappe large couvrant l'écran ; decay abaissé à 0,01–0,02 (.01 * Math.random() + .01) pour des flammes qui atteignent le haut du canvas.
Fond de vente flash — Compte à rebours pleine page — Fire Effect exemple 3

③ Fond de vente flash — Compte à rebours pleine page

QuandPage dédiée à une vente flash ou à une offre limitée dans le temps : le feu occupe tout l'arrière-plan et transforme la page entière en signal d'urgence visuelle.
PourquoiLa flamme est la scène entière, pas un accent : elle enveloppe le visiteur dès le chargement. L'urgence agit par atmosphère, sans texte supplémentaire ni icône statique.
RéglagesSpread porté à ±60 px (40120) pour que le feu couvre toute la largeur ; spawn à 4/frame ; decay abaissé à 0,008–0,018 (.01 * Math.random() + .008) pour des flammes très hautes qui atteignent le haut de l'écran.

Comment ça marche

À chaque frame, le canvas n'est pas effacé avec clearRect : un ctx.fillRect semi-transparent rgba(10,10,15,0.15) est appliqué à la place. Les frames précédentes persistent avec 85 % d'opacité restante, créant la traînée de fumée sans aucun stockage de tampon supplémentaire.

3 nouvelles particules sont spawnnées à chaque frame depuis le bas du canvas (y = hauteur − 20 px), à une position x aléatoire ± 20 px autour du centre (t.w/2 + 40*(Math.random()−0.5)). Vitesse verticale initiale : −2 à −6 px/frame (montée) ; dérive horizontale : ±1 px/frame. La décélération est quasi nulle : vy *= 0.99 — les particules montent à vitesse quasi constante avant de disparaître par épuisement de leur durée de vie.

Le dégradé de couleur est calculé par vie restante : R = 255, G = floor(200 × life), B = floor(50 × life). Fraîche (life = 1) → jaune-orange (255, 200, 50) ; à mi-vie (0,5) → orange (255, 100, 25) ; en fin de vie → rouge pur qui s'efface. Taille et alpha décroissent en parallèle : size *= 0.98 par frame, alpha = 0.8 × life. Chaque particule vit entre 33 et 100 frames (decay aléatoire 0,01–0,03).

L'effet utilise un requestAnimationFrame non conditionnel : la boucle tourne en permanence, sans IntersectionObserver ni vérification de visibilité. Il n'y a ni API publique, ni gestion du redimensionnement du canvas après l'initialisation — setupCanvas lit les dimensions du parent une seule fois au chargement.

Accessibilité

  • prefers-reduced-motion absent : l'effet ne consulte pas cette préférence OS. L'animation tourne toujours, même si l'utilisateur a activé « Réduire le mouvement ». À traiter manuellement avec window.matchMedia('(prefers-reduced-motion:reduce)').matches avant de lancer le RAF.
  • Le <canvas> ne porte ni aria-hidden, ni role, ni aria-label dans le code fourni — les lecteurs d'écran peuvent l'annoncer comme un élément interactif vide. Ajoutez aria-hidden="true" sur le canvas et un role="img" + aria-label sur le conteneur.
  • Aucune interaction clavier ou pointeur : l'effet est purement contemplatif. Il n'interfère pas avec la navigation au clavier du reste de la page.
  • Les particules les plus vives (jaune-orange sur fond #0a0a0f quasi-noir) dépassent un ratio de contraste 7:1 — lisibilité visuelle élevée.
  • L'information portée (cycle vie = couleur) est exclusivement chromatique : aucune alternative non-colorée n'est fournie. L'effet étant purement décoratif, l'absence d'alternative est acceptable.

Compatibilité navigateur

Nécessite Canvas 2D, requestAnimationFrame et les template literals ES6 — tous les navigateurs modernes depuis 2016.

Chrome 49+✓ Complet
Firefox 45+✓ Complet
Safari 10+✓ Complet
Edge 14+✓ Complet
Mobile iOS✓ Complet
Android Chrome✓ Complet

Sans Canvas 2D, le <code>&lt;canvas&gt;</code> reste vide et silencieux — aucune erreur JS fatale. Le conteneur <code>.ps-canvas-wrap</code> occupe son espace ; ajoutez un fond CSS de secours (ex. dégradé orange→rouge) si la visibilité à l'écran est requise.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
<div class="demo-preview" role="img"
     aria-label="Animation de feu montant en particules jaune-orange-rouge">
  <div class="ps-canvas-wrap">
    <canvas class="ps-canvas" id="psFire"
            aria-hidden="true">
    </canvas>
  </div>
</div>
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Spawn rate (JS : boucle for) 3 par frame for (let n = 0; n < 3; n++) — augmentez à 5–8 pour une flamme dense et large, descendez à 1–2 pour un feu léger et intermittent.
Spread horizontal (JS : 40) ±20 px du centre 40 * (Math.random() − .5) — doublez à 80 pour une flamme large, réduisez à 10 pour une colonne fine centrée sur un bouton.
Vitesse de montée (JS : vy) -2 à -6 px/frame 4 * -Math.random() - 2 — augmentez le multiplicateur (4→6) pour des particules plus rapides ; augmentez le décalage (2→3) pour une vitesse minimale plus élevée.
Taille initiale (JS : size) 3–9 px 6 * Math.random() + 3 — premier terme = amplitude de la variation, second = taille minimale. Ex. grosses braises : 10 * Math.random() + 6.
Durée de vie (JS : decay) 0,01–0,03 par frame .02 * Math.random() + .01 — abaissez pour des particules longues qui montent haut (flamme haute) ; augmentez pour une flamme courte et intense près de la source.
Traînée fumée (JS : fillStyle fond) rgba(10,10,15,0.15) Fond semi-transparent remplaçant le clearRect. Abaissez l'alpha (0,06–0,10) pour une longue traînée vaporeuse ; montez-le (0,30–0,50) pour couper la fumée et garder seulement les particules fraîches.
Palette couleur (JS : formule RGB) jaune→orange→rouge Remplacez rgba(${a},${l},${c},…) — feu bleu-blanc : rgba(${Math.floor(200*i.life)},${Math.floor(200*i.life)},255,…) ; feu vert : rgba(0,255,${Math.floor(200*i.life)},…).

FAQ

L'IIFE se lie à l'id fixe psFire au chargement — une seule instance tourne nativement. Pour plusieurs flammes, extrayez la logique dans une fonction paramétrée par id : function initFire(id){ const t = setupCanvas(id); const e = []; (function n(){…requestAnimationFrame(n)})(); } puis appelez initFire('feu1'), initFire('feu2'), etc. setupCanvas est une fonction globale réutilisable.
Le code ne fournit pas de handle sur le RAF ni d'API publique. Pour le contrôle : stockez le retour de requestAnimationFrame(n) dans une variable externe (let rafId = requestAnimationFrame(n)) et annulez avec cancelAnimationFrame(rafId). Pour relancer, réappellez simplement la fonction de tick.
setupCanvas lit les dimensions du parent via getBoundingClientRect() une seule fois à l'initialisation. Si le conteneur change de taille (resize de fenêtre, panneau accordéon), recalibrez manuellement : canvas.width = wrap.offsetWidth; canvas.height = wrap.offsetHeight; et mettez à jour t.w et t.h. Ajoutez un ResizeObserver sur .ps-canvas-wrap pour automatiser ce recalibrage.