Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Animating bubbles using Canvas

View bubbles-canvas.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
// called once, to initialize
createBubbles: function(){
var self = this,
el = this.element,
width = $(window).width(),
height = $(window).height(),
canvas = document.createElement('canvas');
 
el.style.width = canvas.width = width;
el.style.height = canvas.height = height;
 
el.appendChild(canvas);
 
var bubbles = [];
var ctx = canvas.getContext('2d');
for(var i = 0; i < this.settings.bubbleCount; i++){
// give random diameter, x, y, opacity, speed, amplitude, and outline or fill
var diam = (Math.random() * (this.settings.maxDiam - this.settings.minDiam)) + this.settings.minDiam,
x = Math.floor(Math.random() * width),
y = height + (diam / 2) + Math.random() * 100,
opacity = Math.random(1),
speed = (Math.random() / 2) + 0.1,
amplitude = (Math.random() * 50) + 45,
isOutline = Math.random() > 0.5;
 
// store bubble properties in memory
var bubble = {
startX: x,
x: x,
y: y,
radius: diam / 2,
speed: speed,
opacity: self.map_range(opacity, 0, 1, 0, 0.4),
amplitude: amplitude,
isOutline: isOutline
};
 
bubbles.push(bubble);
 
}
 
 
var count = 0;
// called on each frame
function animate(){
 
// if not active, place at bottom
if(!$(el).data('isPlaying')){
for(var j = 0; j < bubbles.length; j++){
bubbles[j].y = height + (diam / 2);
}
return;
}
 
count++;
 
// clear canvas
ctx.clearRect(0, 0, width, height);
 
for(var i = 0; i < bubbles.length; i++){
var b = bubbles[i];
 
// if reached top, send back to bottom
if(b.y <= b.radius * -2){
b.y = window.innerHeight + b.radius;
}
 
// move upwards, with repetitive oscillation on the x-axis
b.y = b.y - b.speed;
b.x = b.startX + Math.sin(count / b.amplitude) * 50;
 
ctx.beginPath();
// outline some, fill others
if(b.isOutline){
ctx.strokeStyle = 'rgb(94,202,255)';
ctx.lineWidth = 2;
ctx.arc(b.x, b.y, b.radius, 0, 2 * Math.PI, false);
ctx.stroke();
}else{
ctx.fillStyle = 'rgba(94,202,255, ' + b.opacity + ')';
ctx.arc(b.x, b.y, b.radius, 0, 2 * Math.PI, false);
ctx.fill();
}
}
}
 
 
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
(function animloop(){
requestAnimFrame(animloop);
animate();
})();
 
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.