Reputation: 67
I want to create a confetti effect (screen shot attached) where the flakes should be TRIANGULAR shape(currently they are RECTANGULAR) . I am using the following javascript code to get the effect. However, i want the flakes to start falling from top to bottom when a webpage got opened. Right now the moment we open the page the page is flooded by the flakes. I was looking, how i can blank the screen and make the flakes come down slowly. Can anyone please help me to sort out this effect:
window.onload = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var W = window.innerWidth;
var H = window.innerHeight;
canvas.width = W;
canvas.height = H;
var mp = 1000; //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() * 18 + 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();
}
var angle = 0;
function update() {
angle += 0.01;
for (var i = 0; i < mp; i++) {
var p = particles[i];
p.y += Math.cos(angle + p.d) + 1 + p.r / 2;
p.x += Math.sin(angle) * 2;
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
};
}
}
}
}
setInterval(draw, 20);
}
<canvas id="canvas"></canvas>
Fiddle JS Fiddle link
End Goal: Image
Upvotes: 0
Views: 3423
Reputation: 486
I made a slight edit to the answer above to tweek it more towards your specifications. Edited the Y component so triangles cannot go past the middle of the canvas. Secondly, made the triangles begin at the top of the canvas. Hopefully this helps.
EDIT : Is this what you were looking for?
Side Note : I added a Math.random() * 7 in the draw() function because I think the effect is cool but if you don't like it, replace it with a 10 (that was what it was set to before.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var W = window.innerWidth;
var H = window.innerHeight - 30;
canvas.width = W;
canvas.height = H;
var particles = [];
for (var i = 0; i < 100; i++) {
addParticle();
}
setInterval(addParticle(), 10);
/* Add a single particle */
function addParticle() {
if (particles.length > 1000) {
return false;
}
particles.push({
x: Math.random() * W, //x-coordinate
y: H, //y-coordinate
r: Math.random() * 18 + 1, //radius
d: Math.random() * particles.length, //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
});
}
/* Draw the particles */
function draw() {
ctx.clearRect(0, 0, W, H);
for (var i = 0; i < particles.length; i++) {
var p = particles[i];
ctx.beginPath();
ctx.lineWidth = p.r;
ctx.fillStyle = p.color;
ctx.moveTo(p.x, p.y);
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.lineTo(p.x + 10, p.y);
ctx.lineTo(p.x + 5, p.y + (Math.random() * 7));
ctx.fill();
}
update();
}
var angle = 0.02;
function update() {
for (var i = 0; i < particles.length; i++) {
var p = particles[i];
p.y += Math.cos(angle) + 1 + p.r / 10;
p.x += Math.sin(angle) * 2;
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
};
}
}
}
}
setInterval(draw, 20);
canvas {
z-index: 999;
}
.thankYouBanner {
position:absolute;
height:30px;
bottom:20%;
left:50%;
z-index: 1000;
}
.thankYouBanner h2 {
position:relative;
text-align:center;
width: 100%;
left: -50%;
color: #fff;
background-color: rgba(0,0,0,0.6);
box-shadow: 0 0 15px 10px #fff;
padding-left: 10px;
padding-right: 10px;
padding-top: 5px;
padding-bottom: 5px;
border-radius: 10px;
}
<canvas id="canvas"></canvas>
<div class="thankYouBanner">
<h2>
Thank You, John Doh
</h2>
</div>
Upvotes: 1
Reputation: 91
To make a triangle, you'll want to draw a shape, rather than drawing a thick line.
// Rectangle
ctx.strokeStyle = p.color;
ctx.moveTo(p.x, p.y);
ctx.lineTo(p.x + p.tilt + p.r / 2, p.y + p.tilt);
ctx.stroke();
// Triangle
ctx.fillStyle = p.color;
ctx.moveTo(p.x, p.y);
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.lineTo(p.x + 10, p.y);
ctx.lineTo(p.x + 5, p.y + 10);
ctx.fill();
The following code is updated to do both the things you want:
setTimeout
to add a snowflake every tenth of a second. (The loop can also be removed to start with 0 snowflakes, or snowflakes can be added faster/slower by changing the timeout.)Fiddle: https://jsfiddle.net/72dun3fx/13/
window.onload = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var W = window.innerWidth;
var H = window.innerHeight;
var particles = [];
var angle = 0;
canvas.width = W;
canvas.height = H;
// Add starting particles
for (var i = 0; i < 5; i++) {
addParticle();
}
// Add a particle every tenth of a second
setInterval(addParticle, 100);
// Update the particles so they fall
setInterval(draw, 20);
// Add a single particle
function addParticle() {
if (particles.length > 1000) {
return false;
}
particles.push({
x: Math.random() * W, //x-coordinate
y: Math.random() * H, //y-coordinate
r: Math.random() * 18 + 1, //radius
d: Math.random() * particles.length, //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
});
}
/* Draw the particles */
function draw() {
ctx.clearRect(0, 0, W, H);
for (var i = 0; i < particles.length; i++) {
var p = particles[i];
ctx.beginPath();
ctx.lineWidth = p.r;
ctx.fillStyle = p.color;
ctx.moveTo(p.x, p.y);
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.lineTo(p.x + 10, p.y);
ctx.lineTo(p.x + 5, p.y + 10);
ctx.fill();
}
update();
}
function update() {
angle += 0.01;
for (var i = 0; i < particles.length; i++) {
var p = particles[i];
p.y += Math.cos(angle + p.d) + 1 + p.r / 2;
p.x += Math.sin(angle) * 2;
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
};
}
}
}
}
};
<canvas id="canvas"></canvas>
Upvotes: 1