2013-05-01 23 views
20

編輯:試圖在HTML5中創建五彩紙屑效果,如何爲每個元素獲取不同的填充顏色?

對於任何人誰好奇,這裏是最終的結果。

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


我建過我在這個環節

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

我想使這個更多的紙屑掉落的效果比雪效果發現的代碼,我需要使每個元素具有不同的顏色。但似乎一次就爲整個畫布設置了填充顏色。

有沒有一種方法來爲每個元素指定不同的填充顏色,還是我以完全錯誤的方式去做這件事?

感謝

更新:這裏是如果任何人有需要紙屑

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); 

}

回答

5

嘗試像這樣的成品:http://jsfiddle.net/vxP5q/

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); 
} 

我做了什麼。在生成像素的位置,我添加了一種獨特的(隨機)顏色。在更新的地方,我確保顏色被改變,並且它的繪製位置已經改變了,這樣它就會爲每個五彩紙屑項目創建一個不透明路徑。

+0

完美!正是我所期待的。太感謝了! – Smeegs 2013-05-01 17:26:49

3

偉大的問題。考慮在附圖循環用於樣品:

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(); 

它正在一個路徑,增加了許多弧,然後填充它一次

要更改它,您需要每個粒子填充一次。你還需要給每個粒子獨特的顏色:

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(); 
} 

注意如何beginPath()fill()現在循環。這很重要,因爲每個弧線都需要自己的路徑和填充。這比用一條路徑製作它們要慢得多,但如果你想要不同顏色的粒子,這是必要的。

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)" 
}) 

這裏有一個工作示例:

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

1

這裏是立足崗位由尼爾斯一個版本,我想一個可重用的對象,我可以打電話,並添加到任何頁面。

用法:

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

代碼:

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; 
} 
相關問題