Skip to content

Instantly share code, notes, and snippets.

@DevJMD
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DevJMD/074d8be96153b10000db to your computer and use it in GitHub Desktop.
Save DevJMD/074d8be96153b10000db to your computer and use it in GitHub Desktop.
SnowJS Prototype Inheritance
var snow = new SnowJS('snow');
// Or...
var snow = new SnowJS('snow', { /* Options */ });
/* global window: false */
/* global document: false */
/* global requestAnimFrame: false */
'use strict';
var _plumpExtend = function(defaults, options) {
var extended = {};
var prop;
for (prop in defaults) {
if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
extended[prop] = defaults[prop];
}
}
for (prop in options) {
if (Object.prototype.hasOwnProperty.call(options, prop)) {
extended[prop] = options[prop];
}
}
return extended;
};
var SnowJS = function(id, options) {
this.canvas = document.getElementById(id);
var defaults = {
particleSize: 3,
maxParticles: 550,
particleOpacity: 1,
particleVelocity: 0.001
};
this.options = _plumpExtend(defaults, options);
if(this.canvas && this.canvas !== "null" && this.canvas !== "undefined") {
this.initialize();
}
};
SnowJS.prototype.initialize = function() {
var particleSize = this.options.particleSize,
maxParticles = this.options.maxParticles,
particleOpacity = this.options.particleOpacity,
particleVelocity = this.options.particleVelocity;
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
// Create empty particle array
var particles = [];
// Initialize canvas
var canvas = this.canvas;
var ctx = canvas.getContext('2d');
// Get parent width & height
var parentWidth = this.canvas.parentNode.offsetWidth;
var parentHeight = this.canvas.parentNode.offsetHeight;
// Smaller screens get funky with lots of snow.
// Let's reduce the real estate consumption.
if (parentWidth < 580) {
maxParticles = 75;
} else if (parentWidth > 580 && parentWidth < 1199) {
maxParticles = 250;
}
// Apply canvas size based on window width & height.
// This can be changed to bound within an element instead.
canvas.width = parentWidth;
canvas.height = parentHeight;
// Push particle iteration
for (var i = 0; i < maxParticles; i++) {
particles.push({
// Particle x position
x: Math.random() * parentWidth,
// Particle y position
y: Math.random() * parentHeight,
// Particle radius
r: Math.random(Math.min(particleSize)) * particleSize,
// Particle density
d: Math.random() * maxParticles
});
}
// Render particles
function render() {
ctx.clearRect(0, 0, parentWidth, parentHeight);
ctx.fillStyle = 'rgba(255, 255, 255, ' + particleOpacity + ')';
ctx.beginPath();
// Iterate the particles.
for(var i = 0; i < maxParticles; i++) {
var p = particles[i];
// Move particles along x, y.
ctx.moveTo(p.y, p.y);
// Draw particle.
ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, true);
}
ctx.fill();
update();
}
// To create a more dynamic and organic flow, we need to apply an
// incremental 'angle' that will iterate through each particle flow.
var angle = particleVelocity;
// Update particles
function update() {
for (var i = 0; i < maxParticles; i++) {
var p = particles[i];
// Offset the particles flow based on the angle.
p.y += Math.cos(angle + p.d) + p.r;
p.x += Math.sin(angle) / 10;
// Sending flakes back from the top when it exits
// Lets make it more organic and let the flakes enter from the left and right.
if(p.x > parentWidth + 2.5 || p.x < - 2.5 || p.y > parentHeight) {
if(i % 3 > 0) {
// If exiting the bottom
particles[i] = {
x: Math.random() * parentWidth,
y: -5,
r: p.r,
d: p.d
};
} else {
// If exiting the right
if(Math.sin(angle) > 0) {
particles[i] = {
x: -5,
y: Math.random() * parentHeight,
r: p.r,
d: p.d
};
} else {
// If exiting the left
particles[i] = {
x: parentWidth + 5,
y: Math.random() * parentHeight,
r: p.r,
d: p.d
};
}
}
}
}
}
(function runtime() {
requestAnimFrame(runtime);
render();
})();
};
"use strict";var _plumpExtend=function(e,t){var n={};var r;for(r in e){if(Object.prototype.hasOwnProperty.call(e,r)){n[r]=e[r]}}for(r in t){if(Object.prototype.hasOwnProperty.call(t,r)){n[r]=t[r]}}return n};var SnowJS=function(e,t){this.canvas=document.getElementById(e);var n={particleSize:3,maxParticles:550,particleOpacity:1,particleVelocity:.001};this.options=_plumpExtend(n,t);console.log(this.options);this.initialize()};SnowJS.prototype.initialize=function(){function l(){o.clearRect(0,0,u,a);o.fillStyle="rgba(255, 255, 255, "+n+")";o.beginPath();for(var e=0;e<t;e++){var r=i[e];o.moveTo(r.y,r.y);o.arc(r.x,r.y,r.r,0,Math.PI*2,true)}o.fill();h()}function h(){for(var e=0;e<t;e++){var n=i[e];n.y+=Math.cos(c+n.d)+n.r;n.x+=Math.sin(c)/10;if(n.x>u+2.5||n.x<-2.5||n.y>a){if(e%3>0){i[e]={x:Math.random()*u,y:-5,r:n.r,d:n.d}}else{if(Math.sin(c)>0){i[e]={x:-5,y:Math.random()*a,r:n.r,d:n.d}}else{i[e]={x:u+5,y:Math.random()*a,r:n.r,d:n.d}}}}}}var e=this.options.particleSize,t=this.options.maxParticles,n=this.options.particleOpacity,r=this.options.particleVelocity;window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(e){window.setTimeout(e,1e3/60)}}();var i=[];var s=this.canvas;var o=s.getContext("2d");var u=this.canvas.parentNode.offsetWidth;var a=this.canvas.parentNode.offsetHeight;console.log(u);if(u<580){t=75}else if(u>580&&u<1199){t=250}s.width=u;s.height=a;for(var f=0;f<t;f++){i.push({x:Math.random()*u,y:Math.random()*a,r:Math.random(Math.min(e))*e,d:Math.random()*t})}var c=r;(function p(){requestAnimFrame(p);l()})()}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment