Skip to content

Instantly share code, notes, and snippets.

@charlenopires
Created November 28, 2014 01:42
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 charlenopires/d4295a42500df017c735 to your computer and use it in GitHub Desktop.
Save charlenopires/d4295a42500df017c735 to your computer and use it in GitHub Desktop.
waves with metablobs
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
var PARAMS = {
height: 400,
damp: 0.04,
spread: 0.1,
k: 0.025,
g: 0.65,
nParticles: 20
}
var SPRING_SPACING = 4;
var NUM_SPRINGS = Math.ceil(WIDTH/SPRING_SPACING);
/*****
CANVAS
*****/
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.width = WIDTH;
canvas.height = HEIGHT;
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#f00';
var grd = ctx.createLinearGradient(0,0,0,PARAMS.height);
grd.addColorStop(0, 'red');
grd.addColorStop(1, 'orange');
ctx.fillStyle = grd;
var c2 = document.createElement('canvas');
c2.width = WIDTH;
c2.height = HEIGHT;
var ctx2 = c2.getContext('2d');
ctx2.fillStyle = '#fff';
/*****
Spring
*****/
var Spring = function(k, x, d) {
this.x = x;
this.k = k;
this.v = 0;
this.d = d;
}
/*****
Splash Particle
*****/
var Droplet = function(x, y, v) {
this.x = x;
this.y = y;
this.vx = Math.random() * 10 - 5;
this.vy = - Math.random() * 4 - v;
this.r = Math.random()*6 + 2;
}
var particles = [];
var addSplashParticles = function(x, y, v) {
for (var i = 0; i < PARAMS.nParticles; i++) {
particles.push(new Droplet(x + Math.random()*10 - 5, y + Math.random()*10 - 5, v));
}
}
var i;
/*****
springs
*****/
var springs = [];
for (i = -10; i < NUM_SPRINGS + 50; i++) {
springs.push(new Spring(PARAMS.k, 0, PARAMS.damp));
}
/*****
Splash
*****/
document.body.addEventListener("click", function(e) {
var intensity = Math.round((e.clientY - PARAMS.height)/10);
var i = Math.round((e.clientX-40)/SPRING_SPACING);
var total = Math.ceil(80/SPRING_SPACING);
var j;
for (j = 0; j < total; j++) {
if (springs[i+j]) {
springs[i+j].v = intensity;
}
}
addSplashParticles(e.clientX, PARAMS.height + 2*intensity, Math.abs(intensity)*0.5);
});
/*****
drawSprings
*****/
var drawSprings = function() {
ctx.fillStyle = '#fff';
ctx.beginPath();
ctx.moveTo(0, HEIGHT);
springs.forEach(function(s, i) {
ctx.lineTo(SPRING_SPACING*i, PARAMS.height+s.x);
});
ctx.lineTo(WIDTH, HEIGHT);
/*ctx2.shadowBlur = 20;
ctx2.shadowOffsetY = -10;
ctx2.shadowOffsetX = -5;
ctx2.shadowColor = '#fff';*/
ctx.fill();
}
/*****
updateSprings
*****/
var updateSprings = function() {
springs.forEach(function(s) {
s.a = -s.k * s.x - s.d * s.v;
s.x += s.v;
s.v += s.a;
});
var i, j, leftDelta = [], rightDelta = [];
for (j = 0; j < 8; j++) {
for (i = 0; i < springs.length; i++) {
if (i > 0) {
leftDelta[i] = PARAMS.spread * (springs[i].x - springs[i-1].x);
springs[i-1].v += leftDelta[i];
}
if (i < springs.length - 1) {
rightDelta[i] = PARAMS.spread * (springs[i].x - springs[i+1].x);
springs[i+1].v += rightDelta[i];
}
}
for (i = 0; i < springs.length; i++) {
if (i > 0) {
springs[i-1].x += leftDelta[i];
}
if (i < springs.length - 1) {
springs[i+1].x += rightDelta[i];
}
}
}
}
/********
SPLASHES
********/
var updateParticles = function() {
for (var i = particles.length-1; i >= 0; i--) {
if (particles[i].y > PARAMS.height + 100) {
particles.splice(i, 1);
} else {
particles[i].vy += PARAMS.g;
particles[i].y += particles[i].vy;
particles[i].x += particles[i].vx;
}
}}
var drawParticles = function() {
ctx2.fillStyle = '#fff';
particles.forEach(function(p) {
ctx2.beginPath();
ctx2.arc(p.x, p.y, p.r, 0, 2*Math.PI, false);
ctx2.fill();
});
}
var drawBackground = function() {
ctx.fillStyle = grd;
ctx.fillRect(0,0,WIDTH,HEIGHT);
ctx2.clearRect(0,0,WIDTH,HEIGHT);
}
var commitDrawing = function() {
//ctx.drawImage(c2, 0, 0);
}
/********
METABLOBS
(using canvas + gradients)
********/
var metablob = function() {
/*var data = ctx2.getImageData(0,0,WIDTH,HEIGHT);
for (var i = 0; i < data.data.length; i += 4) {
if (data.data[i+3] > 150) {
data.data[i] = 255;
data.data[i+1] = 255;
data.data[i+2] = 255;
//data.data[i+3] = 180;
if (data.data[i+3] < 180) {
data.data[i+3] = 180*(data.data[i+3]-150)/30;
} else {
data.data[i+3] = 180;
}
} else {
data.data[i+3] = 0;
}
}
ctx2.putImageData(data,0,0);*/
}
/*****
update
*****/
var update = function() {
drawBackground();
updateParticles();
drawParticles();
updateSprings();
drawSprings();
metablob();
commitDrawing();
requestAnimationFrame(update);
}
requestAnimationFrame(update);
/*****
dat.gui
*****/
var gui = new dat.GUI();
gui.add(PARAMS, 'k', 0, 0.1)
.onChange(function(k) {
springs.forEach(function(s) {
s.k = k;
})
});
gui.add(PARAMS, 'damp', 0, 0.2)
.onChange(function(d) {
springs.forEach(function(s) {
s.d = d;
})
});
gui.add(PARAMS, 'spread', 0, 0.2);
gui.add(PARAMS, 'height', 0, 1000);
gui.add(PARAMS, 'nParticles', 0, 100);
gui.add(PARAMS, 'g', 0, 0.8);
body {
margin: 0;
padding: 0;
overflow: hidden;
background: black;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment