编辑:
对于任何好奇的人,这是最终结果。
https://jsfiddle.net/Javalsu/q1kmLoja/4/
我正在构建在此链接中找到的代码
http://thecodeplayer.com/walkthrough/html5-canvas-snow-effect
我想让这更像是五彩纸屑掉落的效果而不是雪花效果,并且我需要使每个元素具有不同的颜色。 但似乎整个画布的填充颜色都是一次性设置的。
有没有办法为每个元素指定不同的填充颜色,或者我的做法完全错误吗?
谢谢
更新:如果有人需要五彩纸屑,这是成品
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);
}
尝试这样: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);
}
我做了什么。在生成像素的地方,我添加了一种独特的(随机)颜色。在更新的地方,我确保颜色被改变,并且它的绘制位置我已经改变了,这样它就会为每个五彩纸屑项目创建一个独特的路径。
好问题。考虑示例的绘图循环:
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)"
})
这是一个工作示例:
这是基于 Niels 帖子的版本,我想要一个可重用的对象,我可以调用它并将其添加到任何页面。
用途:
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;
}
我认为canvas-confetti比这里的任何其他都更真实,并且它有更多功能:五彩纸屑,雪,烟花等。单击此处进行演示!