Tech things and such
Article / Note
2016/01/24

Feux d'artifices / Particules

Une approche naïve du sujet, ma foi pas si ridicule en terme de performances. Les explosions déclenchent sommairement des effets sonores Web Audio... pas si "right on time" ! Le canvas est interactif (clic+drag pour lancer une fusée).

Quelques finesses (si on peut dire) :

  • chaque fusée a une durée de vol (avant son explosion) et une vitesse initiale aléatoire
  • chaque étoile a une espérance de vie (avant son extinction) aléatoire
  • l'étoile change de couleur selon son âge (table des couleurs), ce qui permet éventuellement de la faire clignoter
  • l'étoile est freinée proportionnellement à sa vitesse (freinage aéro-dynamique, damping) ce qui donne plus de réalisme.
  • les fusées qui vont à haute altitude seront aussi les plus fortes
  • le fond du canvas est transparent, le fond de la div est noir. Ceci pour permettre les effets de filés. Aucun clearRect ou fillRect rect n'est fait lorsque qu'on redessine, mais un filtre de fade sur les 4 couches RGBA est appliqué, ce qui permet de conserver une trace fugace.

Voici le code de ce filtre, qui est également une base minimale pour implémenter un algorithme de traitement d'image :


    // on récupère le contenu bitmap d'un contexte
    var imgData = context.getImageData(0,0,W,H);
    // on récupère les données des pixels
    var d = imgData.data;

    // iterations dans tous les pixels
    // lecture des données des couches dans l'ordre "pixel oriented" (≠ "planar") RGBA, 8bits
    for (var i=0; i < d.length; i+=4) 
    {
        // toutes valeurs : entiers entre 0 et 255
        var r = d[i];
        var g = d[i+1];
        var b = d[i+2];
        var a = d[i+3];

        // ici le fade, il faut l'appliquer sur toutes les couches sans quoi l'effacement est incomplet
        d[i] =   Math.floor(Math.max(0,0.92*r));
        d[i+1] = Math.floor(Math.max(0,0.92*g));
        d[i+2] = Math.floor(Math.max(0,0.92*b));
        d[i+3] = Math.max(0,0.92*a);
    }
    // On peut remplacer les pixels dans le contexte.
    context.putImageData(imgData,0,0);
>> Réagir à cet article