Skip to content

Instantly share code, notes, and snippets.

@assertchris
Created September 19, 2012 12:09
Show Gist options
  • Select an option

  • Save assertchris/3749323 to your computer and use it in GitHub Desktop.

Select an option

Save assertchris/3749323 to your computer and use it in GitHub Desktop.
Vanilla JavaScript, Canvas Confetti
// I don't usually inline my javascript, but when I do it is in Greg's HTML.
(function () {
var last = 0,
vendors = ["ms", "moz", "webkit", "o"];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"];
window.cancelAnimationFrame = window[vendors[x] + "CancelAnimationFrame"] || window[vendors[x] + "CancelRequestAnimationFrame"];
}
if (!window.requestAnimationFrame) window.requestAnimationFrame = function (callback, element) {
var now = new Date().getTime(),
next = Math.max(0, 16 - (now - last)),
id = window.setTimeout(function () {
callback(now + next);
}, next);
last = now + next;
return id;
};
if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function (id) {
clearTimeout(id);
};
function Animation(step, element) {
var id, last;
function start() {
stop();
last = Date.now();
run();
}
function run() {
id = requestAnimationFrame(function (now) {
step(now - last);
last = now;
run();
}, element);
}
function stop() {
if (id) {
cancelAnimationFrame(id);
id = null;
}
}
this.start = start;
this.stop = stop;
}
function Piece(context, x, y) {
var type = Math.floor(Math.random() * 5),
d = .1,
dx = 0,
dy = 0,
tx = x,
ty = y,
m = 0;
function draw() {
value = Piece.values[Math.floor(Math.random() * Piece.values.length)];
context.fillStyle = "rgba("+value[0]+", "+value[1]+", "+value[2]+", " + ((100 - m) / 100) + ")";
context.fillRect(tx, ty, 10, 10);
}
function launch() {
var a = Math.random() * Math.PI * 2;
m = 0;
tx = x;
ty = y;
switch (type) {
case 1:
var s = Math.random() * 2;
break;
case 2:
var s = 2;
break;
case 3:
var s = (Math.PI * 2) - a - Math.random();
break;
case 4:
var s = a - Math.random();
break;
default:
var s = Math.random() * 2;
if (Math.random() > .6) {
s = 1.5;
}
}
dx = (s + 4) * Math.sin(a);
dy = (s + 4) * Math.cos(a) - 2;
draw();
}
function move() {
dy += d;
tx += dx;
ty += dy;
m++;
draw();
}
function relinquish() {
return m == 100;
}
launch();
return {
"move": move.bind(this),
"launch": launch.bind(this),
"relinquish": relinquish.bind(this)
};
}
Piece.values = [
[59, 4, 10],
[122, 27, 35],
[228, 174, 92],
[248, 229, 182],
[9, 10, 9],
[47, 45, 47]
];
function Pieces(canvas, x, y) {
var pieces = [],
context = canvas.getContext("2d"),
canvas_width = canvas.width,
canvas_height = canvas.height;
function advance(new_pieces) {
var index, piece;
for (index = pieces.length - 1; index >= 0; index--) {
piece = pieces[index];
piece.move();
if (piece.relinquish()) {
piece.launch();
new_pieces -= 1;
}
}
while (new_pieces > 0) {
pieces.push(new Piece(context, x, y));
new_pieces -= 1;
}
}
function update(time) {
var new_pieces = (Math.random() * 2) | 0;
context.save();
context.clearRect(0, 0, canvas_width, canvas_height);
advance(new_pieces);
context.restore();
}
this.update = update;
}
window.Confetti = {
"Piece": Piece,
"Pieces": Pieces,
"Animation": Animation
};
})();
@assertchris
Copy link
Copy Markdown
Author

var canvas = document.geTElementById("confetti");

canvas.width = 970;
canvas.height = 500;

var pieces = new Confetti.Pieces(canvas, canvas.width / 2, canvas.height - (canvas.height / 4)),
animation = new Confetti.Animation(pieces.update, canvas);

animation.start();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment