2013-05-01 68 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; 
} 
相关问题