Skip to content

Instantly share code, notes, and snippets.

@neave
Last active August 6, 2018 11:57
Show Gist options
  • Save neave/7585734 to your computer and use it in GitHub Desktop.
Save neave/7585734 to your computer and use it in GitHub Desktop.
Wobbly Surface with canvas
<!DOCTYPE html>
<html>
<head>
<style> body { margin: 0; } </style>
</head>
<body>
<canvas id="wobble"></canvas>
<script src="http://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
<script src="wobble.js"></script>
</body>
</html>
// Wobbly Surface - mouse over for fun blobbiness!
// As used on http://blog.neave.com
// by Paul Neave
// @neave
// requestAnimationFrame shim
var i = 0,
lastTime = 0,
vendors = ['ms', 'moz', 'webkit', 'o'];
while (i < vendors.length && !window.requestAnimationFrame) {
window.requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[i] + 'CancelAnimationFrame'] || window[vendors[i] + 'CancelRequestAnimationFrame'];
i++;
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime(),
timeToCall = Math.max(0, 1000 / 60 - currTime + lastTime),
id = setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}
var mouseX = 0,
mouseY = -100,
mouseDist = 150,
viscosity = 30,
damping = 0.1,
motion = 1,
totalPoints = 20,
updateID,
points,
color = '#f09',
canvas = document.getElementById('wobble'),
c = canvas.getContext('2d');
function Point(x, y) {
this.x = x;
this.ix = x;
this.vx = 0;
this.y = y;
this.iy = y;
this.vy = 0;
}
Point.prototype.move = function() {
this.vx += (this.ix - this.x) / viscosity * canvas.width;
this.vy += (this.iy - this.y) / viscosity * canvas.height;
var dx = this.x * canvas.width - mouseX,
dy = this.y * canvas.height - mouseY;
if (Math.sqrt(dx * dx + dy * dy) < mouseDist) {
var a = Math.atan2(dy, dx);
this.vx += (Math.cos(a) * viscosity - dx) / viscosity;
this.vy -= (Math.sin(a) * viscosity - dy) / viscosity;
}
this.vx *= (1 - damping);
this.vy *= (1 - damping);
this.x += this.vx / canvas.width;
this.y += this.vy / canvas.height;
if (this.y < 0) {
this.y = 0;
} else if (this.y > 1) {
this.y = 1;
}
};
function init() {
var w = canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
motion = 1;
points = [];
totalPoints = Math.max(Math.round(w / 50), 10);
for (var i = totalPoints; i--; ) {
points.push(new Point(i / (totalPoints - 3), 0.5));
}
}
function update() {
updateID = requestAnimationFrame(update);
if (motion < 0.04) {
return;
}
var p = points[totalPoints - 1],
cx,
cy;
c.clearRect(0, 0, canvas.width, canvas.height);
c.fillStyle = color;
c.beginPath();
c.moveTo(p.x * canvas.width, p.y * canvas.height);
motion = 0;
for (var i = totalPoints - 1; i > 0; i--) {
p = points[i];
p.move();
motion += Math.abs(p.vx) + Math.abs(p.vy);
cx = (p.x + points[i - 1].x) / 2 * canvas.width;
cy = (p.y + points[i - 1].y) / 2 * canvas.height;
if (i === 1) {
cx = canvas.width;
} else if (i === totalPoints - 1) {
p.x = 0;
}
c.bezierCurveTo(p.x * canvas.width, p.y * canvas.height, cx, cy, cx, cy);
}
c.lineTo(canvas.width, canvas.height);
c.lineTo(0, canvas.height);
c.closePath();
c.fill();
}
function wobble() {
for (var i = totalPoints - 1; i > 0; i--) {
points[i].vy += Math.random() * 100 - 50;
}
}
window.onload = function() {
var gui = new dat.GUI();
gui.closed = true;
gui.add(this, 'viscosity', 10, 50);
gui.add(this, 'damping', 0, 0.2);
gui.add(this, 'mouseDist', 10, 300);
gui.add(this, 'wobble');
gui.addColor(this, 'color');
window.addEventListener('mousemove', function(event) {
mouseX = event.pageX;
mouseY = event.pageY;
motion = 1;
});
canvas.addEventListener('mousedown', wobble);
window.onresize = function(event) {
cancelAnimationFrame(updateID);
init();
update()
};
init();
wobble();
update();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment