Skip to content

Instantly share code, notes, and snippets.

@kieranjones
Last active February 7, 2017 07:45
Show Gist options
  • Save kieranjones/b1420b5e83a10d60e3a4c9c018a8929f to your computer and use it in GitHub Desktop.
Save kieranjones/b1420b5e83a10d60e3a4c9c018a8929f to your computer and use it in GitHub Desktop.
React Confetti Canvas
// For jsbin
// noprotect
/* Written by Kieran Jones on 07/02/2017
Based on https://codepen.io/linrock/pen/Amdhr
Live demo here http://jsbin.com/zejihirewu/1/edit?js,output
MIT License
*/
class CanvasComponent extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
ctx: null,
NUM_CONFETTI: 100,
PI_2: 5 * Math.PI,
confetti: [],
w: 1920,
h: 58
};
}
componentDidMount() {
const ctx = this.refs.canvas.getContext('2d');
this.setState({
ctx: ctx,
confetti: this.confetti()
});
this.updateCanvas();
}
ConfettiCodeTest() {
const COLORS = [[85, 71, 106], [174, 61, 99], [219, 56, 83], [244, 92, 68], [248, 182, 70]];
const w = 1920;
const h = 58;
const xpos = 0.5;
this.range = function(a, b){
return (b - a) * Math.random() + a;
};
this.style = COLORS[~~this.range(0, 5)];
this.rgb = "rgba(" + this.style[0] + "," + this.style[1] + "," + this.style[2];
this.r = ~~this.range(2, 6);
this.r2 = 2 * this.r;
this.replace = function() {
this.opacity = 1;
this.dop = 0.03 * this.range(1, 4);
this.x = this.range(-this.r2, w - this.r2);
this.y = this.range(-100, h - this.r2);
this.xmax = w - this.r;
this.ymax = h - this.r;
this.vx = this.range(0, 2) + 8 * xpos - 5;
return this.vy = 0.7 * this.r + this.range(-1, 1);
};
this.replace();
this.draw = function() {
let ref;
this.x += this.vx;
this.y += this.vy;
this.opacity += this.dop;
if (this.opacity > 1) {
this.opacity = 1;
this.dop *= -1;
}
if (this.opacity < 0 || this.y > this.ymax) {
this.replace();
}
if (!((0 < (ref = this.x) && ref < this.xmax))) {
this.x = (this.x + this.xmax) % this.xmax;
}
const retObj = {
x: ~~this.x,
y: ~~this.y,
r: 3,
rgb: this.rgb + "," + this.opacity + ")"
};
return retObj;
};
};
confetti() {
let j;
let ref;
let results = [];
const { NUM_CONFETTI } = this.state;
for (i = j = 1, ref = NUM_CONFETTI; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) {
results.push(new this.ConfettiCodeTest());
}
return results;
};
drawCircle(x, y, r, style) {
const { ctx } = this.state;
ctx.beginPath();
ctx.arc(x, y, r, 0, this.state.PI_2, false);
ctx.fillStyle = style;
return ctx.fill();
};
updateCanvas() {
let c;
let j;
let len;
let results = [];
const { w, h, confetti, ctx } = this.state;
window.requestAnimationFrame(() => this.updateCanvas(ctx));
if (ctx) {
ctx.clearRect(0, 0, w, h);
for (j = 0, len = confetti.length; j < len; j++) {
c = confetti[j];
const draw = c.draw();
results.push(this.drawCircle(draw.x, draw.y, draw.r, draw.rgb));
}
}
return results;
}
render() {
const { w, h } = this.state;
return (
<canvas ref="canvas" width={w} height={h}/>
);
}
}
ReactDOM.render(<CanvasComponent/>, document.getElementById('container'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment