Skip to content

Instantly share code, notes, and snippets.

@thykka
Forked from anonymous/index.html
Last active February 5, 2016 15:26
Show Gist options
  • Save thykka/b52fa356fd98953ce836 to your computer and use it in GitHub Desktop.
Save thykka/b52fa356fd98953ce836 to your computer and use it in GitHub Desktop.
Animooted particle parallax background
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Animooted particle parallax background</title>
<style id="jsbin-css">
body {
background-color: #63BCB3;
font-family: Droid Sans, sans-serif;
margin: 0;
}
canvas {
color: snow;
opacity: .25;
transition: all .5s ease-out;
}
canvas.paused {
opacity: 0;
}
h2 {
position: absolute;
font-size: 2em;
line-height: 0;
top: 0;
left: 0;
width: 100%;
text-align: center;
top: 42%;
white-space: nowrap;
}
</style>
</head>
<body>
<canvas id="bg"></canvas>
<h2>Thank you for your feedback!</h2>
<script id="jsbin-javascript">
console.clear();
var extend = 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 TemplateShape = function (p) {
// returns a cached canvas symbol
var ts = this;
ts.size = p.c.global.size * p.scale;
ts.width = p.c.global.weight * p.scale;
ts.canvas = document.createElement('canvas');
ts.canvas.width = ts.canvas.height = ts.size;
ts.ctx = ts.canvas.getContext("2d");
ts.ctx.fillStyle = p.c.global.fill;
ts.ctx.fillRect(
Math.round((ts.size * 0.5) - (ts.width * 0.5)),
0,
Math.round(ts.width),
Math.round(ts.size)
);
ts.ctx.fillRect(
0,
Math.round((ts.size * 0.5) - (ts.width * 0.5)),
Math.round(ts.size),
Math.round(ts.width)
);
return ts;
};
var Particle = function (c) {
// returns a particle controller
var p = this;
p.c = c;
p.last = 0;
// save the index to break wiggle uniformity
p.index = c.particles.length;
// scale controls the particle's size and in a parallax-like manner
p.scale = Math.random() + 0.5 * 0.5;
// assign random starting position
p.y = Math.floor(Math.random() * p.c.canvas.height);
p.x = Math.floor(Math.random() * p.c.canvas.width);
// create a cached symbol
p.shape = new TemplateShape(p);
p.draw = function () {
p.c.ctx.drawImage(
p.shape.canvas,
Math.round(p.x),
// particles should flow up, hence the subtraction
Math.round(p.c.canvas.height - p.y));
};
p.update = function (t) {
// apply vertical movement
p.delta = t - p.last;
p.y = p.y + (p.c.global.speed * p.scale * (p.delta));
// particle gone beyond canvas' edges?
if(p.y - p.shape.size > p.c.canvas.height) {
// move it back to the opposite edge
p.y = 0 - p.shape.canvas.height;
p.x = Math.floor(Math.random() * p.c.canvas.width);
}
// apply wiggle in x-axis
p.x = p.x + (Math.sin(
p.index + (t / p.c.global.wiggleSpeed )
) * p.scale * p.c.global.wiggle);
p.last = t;
};
p.handleResize = function (c) {
//console.log(c.canvas.width);
};
return p;
};
var Cloud = function (options) {
var c = this;
c.canvas = document.getElementById("bg");
c.canvas.width = window.innerWidth;
c.canvas.height = window.innerHeight;
c.ctx = c.canvas.getContext("2d");
c.global = {
paused: false,
amount: 33, // total amount of particles
size: 100, // base size of particles
weight: 33, // thickness of the symbol
speed: 0.025, // base speed of particles
// particle color should match color defined in canvas' CSS
// NOTE: color is not dynamic
fill: window.getComputedStyle(c.canvas).color,
wiggle: 0.5, // base wiggle amount
wiggleSpeed: 1000 // base wiggle speed (bigger is slower)
};
c.global = extend(c.global, options);
c.particles = []; // individual Particles are stored here
for(var p = 0; p < c.global.amount; p++) {
c.particles.push(new Particle(c));
}
c.update = function (time) {
// set initial time, so that no argument is required for the first call
if(typeof time === "undefined") {
time = 0;
}
// clear the canvas
c.ctx.clearRect(0, 0, c.canvas.width, c.canvas.height);
c.particles.forEach(function(e) {
e.update(time);
});
c.particles.forEach(function(e) {
e.draw();
});
c.raf = window.requestAnimationFrame(c.update);
};
c.handleResize = function () {
c.canvas.width = window.innerWidth;
c.canvas.height = window.innerHeight;
};
c.pause = function () {
if(c.global.paused) {
c.raf = window.requestAnimationFrame(c.update);
c.canvas.classList.remove("paused");
c.global.paused = false;
} else {
window.cancelAnimationFrame(c.raf);
c.canvas.classList.add("paused");
c.global.paused = true;
}
};
window.addEventListener("resize", c.handleResize);
c.canvas.addEventListener("click", c.pause);
return c;
};
var c = new Cloud();
c.update();
</script>
<script id="jsbin-source-css" type="text/css">body {
background-color: #63BCB3;
font-family: Droid Sans, sans-serif;
margin: 0;
}
canvas {
color: rgb(255,250,250);
opacity: .25;
transition: all .5s ease-out;
}
canvas.paused {
opacity: 0;
}
h2 {
position: absolute;
font-size: 2em;
line-height: 0;
top: 0;
left: 0;
width: 100%;
text-align: center;
top: 42%;
white-space: nowrap;
}</script>
<script id="jsbin-source-javascript" type="text/javascript">console.clear();
var extend = 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 TemplateShape = function (p) {
// returns a cached canvas symbol
var ts = this;
ts.size = p.c.global.size * p.scale;
ts.width = p.c.global.weight * p.scale;
ts.canvas = document.createElement('canvas');
ts.canvas.width = ts.canvas.height = ts.size;
ts.ctx = ts.canvas.getContext("2d");
ts.ctx.fillStyle = p.c.global.fill;
ts.ctx.fillRect(
Math.round((ts.size * 0.5) - (ts.width * 0.5)),
0,
Math.round(ts.width),
Math.round(ts.size)
);
ts.ctx.fillRect(
0,
Math.round((ts.size * 0.5) - (ts.width * 0.5)),
Math.round(ts.size),
Math.round(ts.width)
);
return ts;
};
var Particle = function (c) {
// returns a particle controller
var p = this;
p.c = c;
p.last = 0;
// save the index to break wiggle uniformity
p.index = c.particles.length;
// scale controls the particle's size and in a parallax-like manner
p.scale = Math.random() + 0.5 * 0.5;
// assign random starting position
p.y = Math.floor(Math.random() * p.c.canvas.height);
p.x = Math.floor(Math.random() * p.c.canvas.width);
// create a cached symbol
p.shape = new TemplateShape(p);
p.draw = function () {
p.c.ctx.drawImage(
p.shape.canvas,
Math.round(p.x),
// particles should flow up, hence the subtraction
Math.round(p.c.canvas.height - p.y));
};
p.update = function (t) {
// apply vertical movement
p.delta = t - p.last;
p.y = p.y + (p.c.global.speed * p.scale * (p.delta));
// particle gone beyond canvas' edges?
if(p.y - p.shape.size > p.c.canvas.height) {
// move it back to the opposite edge
p.y = 0 - p.shape.canvas.height;
p.x = Math.floor(Math.random() * p.c.canvas.width);
}
// apply wiggle in x-axis
p.x = p.x + (Math.sin(
p.index + (t / p.c.global.wiggleSpeed )
) * p.scale * p.c.global.wiggle);
p.last = t;
};
p.handleResize = function (c) {
//console.log(c.canvas.width);
};
return p;
};
var Cloud = function (options) {
var c = this;
c.canvas = document.getElementById("bg");
c.canvas.width = window.innerWidth;
c.canvas.height = window.innerHeight;
c.ctx = c.canvas.getContext("2d");
c.global = {
paused: false,
amount: 33, // total amount of particles
size: 100, // base size of particles
weight: 33, // thickness of the symbol
speed: 0.025, // base speed of particles
// particle color should match color defined in canvas' CSS
// NOTE: color is not dynamic
fill: window.getComputedStyle(c.canvas).color,
wiggle: 0.5, // base wiggle amount
wiggleSpeed: 1000 // base wiggle speed (bigger is slower)
};
c.global = extend(c.global, options);
c.particles = []; // individual Particles are stored here
for(var p = 0; p < c.global.amount; p++) {
c.particles.push(new Particle(c));
}
c.update = function (time) {
// set initial time, so that no argument is required for the first call
if(typeof time === "undefined") {
time = 0;
}
// clear the canvas
c.ctx.clearRect(0, 0, c.canvas.width, c.canvas.height);
c.particles.forEach(function(e) {
e.update(time);
});
c.particles.forEach(function(e) {
e.draw();
});
c.raf = window.requestAnimationFrame(c.update);
};
c.handleResize = function () {
c.canvas.width = window.innerWidth;
c.canvas.height = window.innerHeight;
};
c.pause = function () {
if(c.global.paused) {
c.raf = window.requestAnimationFrame(c.update);
c.canvas.classList.remove("paused");
c.global.paused = false;
} else {
window.cancelAnimationFrame(c.raf);
c.canvas.classList.add("paused");
c.global.paused = true;
}
};
window.addEventListener("resize", c.handleResize);
c.canvas.addEventListener("click", c.pause);
return c;
};
var c = new Cloud();
c.update();</script></body>
</html>
body {
background-color: #63BCB3;
font-family: Droid Sans, sans-serif;
margin: 0;
}
canvas {
color: snow;
opacity: .25;
transition: all .5s ease-out;
}
canvas.paused {
opacity: 0;
}
h2 {
position: absolute;
font-size: 2em;
line-height: 0;
top: 0;
left: 0;
width: 100%;
text-align: center;
top: 42%;
white-space: nowrap;
}
console.clear();
var extend = 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 TemplateShape = function (p) {
// returns a cached canvas symbol
var ts = this;
ts.size = p.c.global.size * p.scale;
ts.width = p.c.global.weight * p.scale;
ts.canvas = document.createElement('canvas');
ts.canvas.width = ts.canvas.height = ts.size;
ts.ctx = ts.canvas.getContext("2d");
ts.ctx.fillStyle = p.c.global.fill;
ts.ctx.fillRect(
Math.round((ts.size * 0.5) - (ts.width * 0.5)),
0,
Math.round(ts.width),
Math.round(ts.size)
);
ts.ctx.fillRect(
0,
Math.round((ts.size * 0.5) - (ts.width * 0.5)),
Math.round(ts.size),
Math.round(ts.width)
);
return ts;
};
var Particle = function (c) {
// returns a particle controller
var p = this;
p.c = c;
p.last = 0;
// save the index to break wiggle uniformity
p.index = c.particles.length;
// scale controls the particle's size and in a parallax-like manner
p.scale = Math.random() + 0.5 * 0.5;
// assign random starting position
p.y = Math.floor(Math.random() * p.c.canvas.height);
p.x = Math.floor(Math.random() * p.c.canvas.width);
// create a cached symbol
p.shape = new TemplateShape(p);
p.draw = function () {
p.c.ctx.drawImage(
p.shape.canvas,
Math.round(p.x),
// particles should flow up, hence the subtraction
Math.round(p.c.canvas.height - p.y));
};
p.update = function (t) {
// apply vertical movement
p.delta = t - p.last;
p.y = p.y + (p.c.global.speed * p.scale * (p.delta));
// particle gone beyond canvas' edges?
if(p.y - p.shape.size > p.c.canvas.height) {
// move it back to the opposite edge
p.y = 0 - p.shape.canvas.height;
p.x = Math.floor(Math.random() * p.c.canvas.width);
}
// apply wiggle in x-axis
p.x = p.x + (Math.sin(
p.index + (t / p.c.global.wiggleSpeed )
) * p.scale * p.c.global.wiggle);
p.last = t;
};
p.handleResize = function (c) {
//console.log(c.canvas.width);
};
return p;
};
var Cloud = function (options) {
var c = this;
c.canvas = document.getElementById("bg");
c.canvas.width = window.innerWidth;
c.canvas.height = window.innerHeight;
c.ctx = c.canvas.getContext("2d");
c.global = {
paused: false,
amount: 33, // total amount of particles
size: 100, // base size of particles
weight: 33, // thickness of the symbol
speed: 0.025, // base speed of particles
// particle color should match color defined in canvas' CSS
// NOTE: color is not dynamic
fill: window.getComputedStyle(c.canvas).color,
wiggle: 0.5, // base wiggle amount
wiggleSpeed: 1000 // base wiggle speed (bigger is slower)
};
c.global = extend(c.global, options);
c.particles = []; // individual Particles are stored here
for(var p = 0; p < c.global.amount; p++) {
c.particles.push(new Particle(c));
}
c.update = function (time) {
// set initial time, so that no argument is required for the first call
if(typeof time === "undefined") {
time = 0;
}
// clear the canvas
c.ctx.clearRect(0, 0, c.canvas.width, c.canvas.height);
c.particles.forEach(function(e) {
e.update(time);
});
c.particles.forEach(function(e) {
e.draw();
});
c.raf = window.requestAnimationFrame(c.update);
};
c.handleResize = function () {
c.canvas.width = window.innerWidth;
c.canvas.height = window.innerHeight;
};
c.pause = function () {
if(c.global.paused) {
c.raf = window.requestAnimationFrame(c.update);
c.canvas.classList.remove("paused");
c.global.paused = false;
} else {
window.cancelAnimationFrame(c.raf);
c.canvas.classList.add("paused");
c.global.paused = true;
}
};
window.addEventListener("resize", c.handleResize);
c.canvas.addEventListener("click", c.pause);
return c;
};
var c = new Cloud();
c.update();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment