-
-
Save thykka/b52fa356fd98953ce836 to your computer and use it in GitHub Desktop.
Animooted particle parallax background
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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