Edit on
Confetti Effect extracted from <a href="https://trello.com/5m">Trello</a>
<canvas id="confetti" class="confetti js-confetti" width="1024" height="500"></canvas>
var ConfettiMachine, Particle, debounce;

// Polyfill for requestAnimationFrame and cancelAnimationFrame
(function() {
  var b, a, f;
  b = 0;
  a = ["ms", "moz", "webkit", "o"];
  for (f = 0; f < a.length && !window.requestAnimationFrame;) window.requestAnimationFrame = window[a[f] + "RequestAnimationFrame"], window.cancelAnimationFrame = window[a[f] + "CancelAnimationFrame"] || window[a[f] + "CancelRequestAnimationFrame"], ++f;
  window.requestAnimationFrame || (window.requestAnimationFrame = function(a, f) {
    var g, h, c;
    g = (new Date).getTime();
    c = Math.max(0, 16 - (g - b));
    h = window.setTimeout(function() {
      a(g + c)
    }, c);
    b = g + c;
    return h
  });
  window.cancelAnimationFrame ||
    (window.cancelAnimationFrame = function(a) {
    clearTimeout(a)
  })
})();

debounce = function(b, a, f) {
  var d;
  d = void 0;
  return function() {
    var e, g;
    g = this;
    e = arguments;
    clearTimeout(d);
    d = setTimeout(function() {
      d = null;
      f || b.apply(g, e)
    }, a);
    f && !d && b.apply(g, e)
  }
};

ConfettiMachine = function() {
  function b() {
    this.canvas = document.getElementById('confetti');
    this.ctx = this.canvas.getContext("2d");
    this.setCanvasSize();
    this.framesPerParticle = 2;
    this.frameCounter = 0;
    this.particles = [];
    this.particle_index = 0;
    this.makeConfetti();
    this.draw()
  }
  
  b.prototype.makeConfetti = function() {
    var a;
    this.frameCounter++;
    requestAnimationFrame(this.makeConfetti.bind(this));
    if (this.frameCounter / this.particles.length === this.framesPerParticle || 0 === this.particle_index) return a = new Particle(this.canvas), this.particles[this.particle_index] =
      a, a.index = this.particle_index, this.particle_index++
  };
  b.prototype.draw = function() {
    var a, b, d, e;
    requestAnimationFrame(this.draw.bind(this));
    this.ctx.fillStyle = "hsla(0, 0%, 100%, 0.35)";
    this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
    e = this.particles;
    b = 0;
    for (d = e.length; b < d; b++) a = e[b], null != a && (a.draw(), a.life > a.maxLife && delete this.particles[a.index])
  };
  b.prototype.setCanvasSize = function() {
    this.canvas.width = window.innerWidth;
    return this.canvas.height = window.innerHeight
  };
  return b
}();

Particle = function() {
  function b(a) {
    this.canvas = a;
    this.px = Math.random() * (a.width + 10) - 20;
    this.py = -10;
    this.vx = 10 * Math.random() - 5;
    this.vy = 0;
    this.gf = 0.6;
    this.a = 0;
    this.av = 30 * Math.random() - 15;
    this.size = Math.floor(10 * Math.random()) + 20;
    this.sat = Math.floor(70 * Math.random()) + 30;
    this.light = Math.floor(25 * Math.random()) + 50;
    this.alpha = Math.floor(0.7 * Math.random()) + 0.7;
    this.life = 0;
    this.maxLife = 240
  }
  b.prototype.drawRotatedRect = function(a, b, d, e, g, h) {
    var c;
    c = this.canvas.getContext("2d");
    c.save();
    c.beginPath();
    c.translate(a +
      d / 2, b + e / 2);
    c.rotate(h * Math.PI / 180);
    c.rect(-d / 2, -e / 2, d, e);
    c.fillStyle = g;
    c.fill();
    return c.restore()
  };

  b.prototype.draw = function() {
    this.canvas.getContext("2d");
    this.px += this.vx;
    this.py += this.vy;
    this.a += this.av;
    this.vy += this.gf * Math.random();
    this.drawRotatedRect(this.px, this.py, this.size, this.size, "hsla(202, " + this.sat + "%, " + this.light + "%, " + this.alpha + ")", this.a);
    this.alpha -= 0.0070;
    this.life++
  };
  return b
}();

(function() {
  var b;
  this.confettiMachine = new ConfettiMachine;
  b = debounce(function(a) {
    return function() {
      return a.confettiMachine.setCanvasSize()
    }
  }(this), 150);
  return $(window).on("resize", b)
})();
Rerun