2013-05-01 2 views
20

MODIFICA:Cercando di creare un effetto confetti in html5, come ottengo un colore di riempimento diverso per ciascun elemento?

Per chi è curioso, ecco il risultato finale.

http://jsfiddle.net/Javalsu/vxP5q/743/embedded/result/


sto costruendo fuori del codice che ho trovato in questo link

http://thecodeplayer.com/walkthrough/html5-canvas-snow-effect

Voglio fare questo più di un effetto di cadere coriandoli di un effetto neve, e avrei bisogno di rendere ogni elemento di un colore diverso. Ma sembra che il colore di riempimento sia impostato per l'intera tela contemporaneamente.

C'è un modo per specificare un colore di riempimento diverso per ogni elemento o sto andando in questo modo completamente sbagliato?

Grazie

Aggiornamento: Ecco il prodotto finito, se qualcuno ha bisogno di confetti

http://jsfiddle.net/mj3SM/6/

window.onload = function() { 
//canvas init 
var canvas = document.getElementById("canvas"); 
var ctx = canvas.getContext("2d"); 

//canvas dimensions 
var W = window.innerWidth; 
var H = window.innerHeight; 
canvas.width = W; 
canvas.height = H; 

//snowflake particles 
var mp = 200; //max particles 
var particles = []; 
for (var i = 0; i < mp; i++) { 
    particles.push({ 
     x: Math.random() * W, //x-coordinate 
     y: Math.random() * H, //y-coordinate 
     r: Math.random() * 15 + 1, //radius 
     d: Math.random() * mp, //density 
     color: "rgba(" + Math.floor((Math.random() * 255)) + ", " + Math.floor((Math.random() * 255)) + ", " + Math.floor((Math.random() * 255)) + ", 0.8)", 
     tilt: Math.floor(Math.random() * 5) - 5 
    }); 
} 

//Lets draw the flakes 
function draw() { 
    ctx.clearRect(0, 0, W, H); 



    for (var i = 0; i < mp; i++) { 
     var p = particles[i]; 
     ctx.beginPath(); 
     ctx.lineWidth = p.r; 
     ctx.strokeStyle = p.color; // Green path 
     ctx.moveTo(p.x, p.y); 
     ctx.lineTo(p.x + p.tilt + p.r/2, p.y + p.tilt); 
     ctx.stroke(); // Draw it 
    } 

    update(); 
} 

//Function to move the snowflakes 
//angle will be an ongoing incremental flag. Sin and Cos functions will be applied to it to create vertical and horizontal movements of the flakes 
var angle = 0; 

function update() { 
    angle += 0.01; 
    for (var i = 0; i < mp; i++) { 
     var p = particles[i]; 
     //Updating X and Y coordinates 
     //We will add 1 to the cos function to prevent negative values which will lead flakes to move upwards 
     //Every particle has its own density which can be used to make the downward movement different for each flake 
     //Lets make it more random by adding in the radius 
     p.y += Math.cos(angle + p.d) + 1 + p.r/2; 
     p.x += Math.sin(angle) * 2; 

     //Sending flakes back from the top when it exits 
     //Lets make it a bit more organic and let flakes enter from the left and right also. 
     if (p.x > W + 5 || p.x < -5 || p.y > H) { 
      if (i % 3 > 0) //66.67% of the flakes 
      { 
       particles[i] = { 
        x: Math.random() * W, 
        y: -10, 
        r: p.r, 
        d: p.d, 
        color: p.color, 
        tilt: p.tilt 
       }; 
      } else { 
       //If the flake is exitting from the right 
       if (Math.sin(angle) > 0) { 
        //Enter from the left 
        particles[i] = { 
         x: -5, 
         y: Math.random() * H, 
         r: p.r, 
         d: p.d, 
         color: p.color, 
         tilt: p.tilt 
        }; 
       } else { 
        //Enter from the right 
        particles[i] = { 
         x: W + 5, 
         y: Math.random() * H, 
         r: p.r, 
         d: p.d, 
         color: p.color, 
         tilt: p.tilt 
        }; 
       } 
      } 
     } 
    } 
} 

//animation loop 
setInterval(draw, 20); 

}

risposta

5

provare in questo modo: http://jsfiddle.net/vxP5q/

The JS:

window.onload = function(){ 
//canvas init 
var canvas = document.getElementById("canvas"); 
var ctx = canvas.getContext("2d"); 

//canvas dimensions 
var W = window.innerWidth; 
var H = window.innerHeight; 
canvas.width = W; 
canvas.height = H; 

//snowflake particles 
var mp = 25; //max particles 
var particles = []; 
for(var i = 0; i < mp; i++) 
{ 
    particles.push({ 
     x: Math.random()*W, //x-coordinate 
     y: Math.random()*H, //y-coordinate 
     r: Math.random()*4+1, //radius 
     d: Math.random()*mp, //density 
     color: "rgba(" + Math.floor((Math.random() * 255)) +", " + Math.floor((Math.random() * 255)) +", " + Math.floor((Math.random() * 255)) + ", 0.8)" 
    }) 
} 

//Lets draw the flakes 
function draw() 
{ 
    ctx.clearRect(0, 0, W, H); 



    for(var i = 0; i < mp; i++) 
    { 
     var p = particles[i]; 
     ctx.beginPath(); 
     ctx.fillStyle = p.color; 
     ctx.moveTo(p.x, p.y); 
     ctx.arc(p.x, p.y, p.r, 0, Math.PI*2, true); 
     ctx.fill(); 
    } 

    update(); 
} 

//Function to move the snowflakes 
//angle will be an ongoing incremental flag. Sin and Cos functions will be applied to it to create vertical and horizontal movements of the flakes 
var angle = 0; 
function update() 
{ 
    angle += 0.01; 
    for(var i = 0; i < mp; i++) 
    { 
     var p = particles[i]; 
     //Updating X and Y coordinates 
     //We will add 1 to the cos function to prevent negative values which will lead flakes to move upwards 
     //Every particle has its own density which can be used to make the downward movement different for each flake 
     //Lets make it more random by adding in the radius 
     p.y += Math.cos(angle+p.d) + 1 + p.r/2; 
     p.x += Math.sin(angle) * 2; 

     //Sending flakes back from the top when it exits 
     //Lets make it a bit more organic and let flakes enter from the left and right also. 
     if(p.x > W+5 || p.x < -5 || p.y > H) 
     { 
      if(i%3 > 0) //66.67% of the flakes 
      { 
       particles[i] = {x: Math.random()*W, y: -10, r: p.r, d: p.d, color : p.color}; 
      } 
      else 
      { 
       //If the flake is exitting from the right 
       if(Math.sin(angle) > 0) 
       { 
        //Enter from the left 
        particles[i] = {x: -5, y: Math.random()*H, r: p.r, d: p.d, color: p.color}; 
       } 
       else 
       { 
        //Enter from the right 
        particles[i] = {x: W+5, y: Math.random()*H, r: p.r, d: p.d, color : p.color}; 
       } 
      } 
     } 
    } 
} 

//animation loop 
setInterval(draw, 33); 
} 

Quello che ho fatto. Dove vengono generati i pixel, ho aggiunto un colore (casuale) unico. Dove è l'aggiornamento, mi sto assicurando che i colori vengano cambiati e dove è stato disegnato l'ho cambiato in modo che crei un percorso inuuato per ogni oggetto confetti.

+0

PERFETTO! esattamente quello che stavo cercando. Grazie mille! – Smeegs

3

Ottima domanda. Si consideri il ciclo disegno per il campione:

ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; 
ctx.beginPath(); 
for(var i = 0; i < mp; i++) 
{ 
    var p = particles[i]; 
    ctx.moveTo(p.x, p.y); 
    ctx.arc(p.x, p.y, p.r, 0, Math.PI*2, true); 
} 
ctx.fill(); 

Si sta facendo una percorso, aggiungendo molti archi, e quindi riempiendola una volta.

Per cambiarlo, è necessario riempirlo una volta per particella. Si potrà anche dare ad ogni particella un colore unico:

for (var i = 0; i < mp; i++) { 
    var p = particles[i]; 
    ctx.fillStyle = p.color; 
    ctx.beginPath();   
    ctx.moveTo(p.x, p.y); 
    ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, true); 
    ctx.fill(); 
} 

Si noti come beginPath() e fill() sono ora all'interno del ciclo. Questo è importante, perché ogni arco ha bisogno del proprio percorso e riempimento. Questo è molto più lento di renderli tutti con un solo percorso, ma è necessario se vuoi particelle di colore diverso.

Che p.color:

particles.push({ 
    x: Math.random() * W, //x-coordinate 
    y: Math.random() * H, //y-coordinate 
    r: Math.random() * 4 + 1, //radius 
    d: Math.random() * mp, //density 

    // I'm new! 
    color: "rgba(" + Math.floor(Math.random()*255) + 
      ", " + Math.floor(Math.random()*255) + ", 255, 0.8)" 
}) 

Ecco un esempio di lavoro:

http://jsfiddle.net/j4NZK/1/

1

Ecco una versione basata sul post di Niels, volevo un oggetto riutilizzabile che posso chiamare e aggiungere a qualsiasi pagina.

Usage:

confetti.Init(#IdofContainer(div)#, 50,25,100) 

Codice:

var confetti = { 
angle: 0, 
ctx: 0, 
H: 0, 
W: 0, 
mp: 0, 
particles: [], 
endFunction: '', 
Init: function (parent, maxParticles, iCount, speed, endFunct) { 
    confetti.stopped = false; 
    confetti.runner = null; 
    confetti.endFunction = endFunct; 
    var canvas = document.getElementById("confettiCanvasId"); 
    if (canvas) { 
     canvas.parentNode.removeChild(canvas); 
    } 
    canvas = document.createElement('canvas'); 
    canvas.className = 'confettiCanvas'; 
    canvas.id = 'confettiCanvasId' 
    $id(parent).appendChild(canvas); 
    var ctx = canvas.getContext("2d"); 
    var W = $id(parent).clientHeight; 
    var H = $id(parent).clientWidth; 
    canvas.width = W; 
    canvas.height = H; 
    confetti.particles = []; 
    for (var i = 0; i < maxParticles; i++) { 
     confetti.particles.push({ 
      x: Math.random() * W, 
      y: Math.random() * H, 
      r: Math.random() * 4 + 1, //radius 
      d: Math.random() * maxParticles, //density 
      color: "rgba(" + Math.floor((Math.random() * 255)) + ", " + Math.floor((Math.random() * 255)) + ", " + Math.floor((Math.random() * 255)) + ", 0.8)" 
     }); 
    } 
    myCounter = new confetti.Counter({ 
     seconds: iCount, 
     speed: speed, 
     onUpdateStatus: function (sec) { 
      $l(Math.random() * 255) 
      ctx.clearRect(0, 0, W, H); 
      for (var i = 0; i < maxParticles; i++) { 
       var p = confetti.particles[i]; 
       ctx.beginPath(); 
       ctx.fillStyle = p.color; 
       ctx.moveTo(p.x, p.y); 
       ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, true); 
       ctx.fill(); 
      } 

      confetti.angle += 0.01; 
      for (var i = 0; i < maxParticles; i++) { 
       var p = confetti.particles[i]; 
       p.y += Math.cos(confetti.angle + p.d) + 1 + p.r/2; 
       p.x += Math.sin(confetti.angle) * 2; 
       if (p.x > W + 5 || p.x < -5 || p.y > H) { 
        if (i % 3 > 0) //66.67% of the flakes 
        { 
         confetti.particles[i] = {x: Math.random() * W, y: -10, r: p.r, d: p.d, color: p.color}; 
        } 
        else { 
         if (Math.sin(confetti.angle) > 0) { 
          confetti.particles[i] = {x: -5, y: Math.random() * H, r: p.r, d: p.d, color: p.color}; 
         } 
         else { 
          confetti.particles[i] = {x: W + 5, y: Math.random() * H, r: p.r, d: p.d, color: p.color}; 
         } 
        } 
       } 
      } 
     }, 
     onCounterEnd: function() { 
      stopTimer(); 
      myCounter.stop(); 
      confetti.Stop(); 
     }}); 
    myCounter.start(); 
}, 
FadeOut:function fadeOut() { 
    var alpha = 1.0; // full opacity 
    for (var i = 0; i < confetti.particles.length; i++) { 
     var p = confetti.particles[i]; 
     interval = setInterval(function() { 
      //confetti.canvas.width = confetti.canvas.width; // Clears the canvas 
      p.color = "rgba(255, 0, 0, " + alpha + ")"; 
      alpha = alpha - 0.05; // decrease opacity (fade out) 
      if (alpha < 0) { 
       //confetti.canvas.width = confetti.canvas.width; 
       clearInterval(interval); 
      } 
     }, 50); 


    } 
     }, 
Counter: function Countdown(options) { 
    var timer, 
     instance = this, 
     seconds = options.seconds || 10, 
     updateStatus = options.onUpdateStatus || function() { 
     }, 
     counterEnd = options.onCounterEnd || function() { 
     }; 

    function decrementCounter() { 
     updateStatus(seconds); 
     if (seconds === 0) { 
      counterEnd(); 
      instance.stop(); 
     } 
     seconds--; 
    } 

    this.start = function() { 
     clearInterval(timer); 
     timer = 0; 
     seconds = options.seconds; 
     timer = setInterval(decrementCounter, options.speed); 
    }; 

    this.stop = function() { 
     clearInterval(timer); 
    }; 
}, 
Stop: function stop() { 
    $('#confettiCanvasId').fadeOut(); 
    setTimeout(function(){ 
     var canvas = document.getElementById("confettiCanvasId"); 
     if (canvas) { 
      canvas.parentNode.removeChild(canvas); 
     } 
     if (confetti.endFunction) { 
      confetti.endFunction(); 
     } 
    },1000); 

} 
}; 

CSS:

.confettiCanvas{ 
overflow: hidden; 
position: absolute; 
height: 100%; 
width: 100%; 
top: 0; 
left: 0; 
}