HTML5 Canvas Oscillating Bubble
<!DOCTYPE HTML>
<html>
<head>
<script>
var t=0; // time in ms
var fps = 50; // frames per second
var timeInterval = 1000 / fps; // in ms
var canvas = null; // canvas DOM object
var context = null; // canvas context
var bubbleExpandVelocity = 50; // pixels / second
var bubbleDistEachFrame = bubbleExpandVelocity *
timeInterval / 1000; // ms
var bubble=null;
function Bubble(centerPoint,volume,width,maxWidth,widthIncreasing) {
this.centerPoint = centerPoint;
this.volume=volume;
this.width=width;
this.maxWidth=maxWidth;
this.widthIncreasing=widthIncreasing;
this.oscillate = function() {
if (this.widthIncreasing && this.width > this.maxWidth) {
this.widthIncreasing=false;
}
if (!this.widthIncreasing && this.width < this.volume
/ this.maxWidth) {
this.widthIncreasing=true;
}
if (this.widthIncreasing) {
this.width+=bubbleDistEachFrame;
}
else {
this.width-=bubbleDistEachFrame;
}
}
}
function Point(x,y) {
this.x=x;
this.y=y;
}
function init() {
canvas=document.getElementById("myCanvas");
context=canvas.getContext("2d");
initStageObjects();
drawStageObjects();
setInterval(updateStage, timeInterval);
}
function updateStage() {
t+=timeInterval;
clearCanvas();
updateStageObjects();
drawStageObjects();
}
function initStageObjects() {
centerPoint = new Point(285,100);
var volume=10000;
var width=100;
var maxWidth = 102;
bubble = new Bubble(centerPoint,volume,width,maxWidth,true);
}
function drawStageObjects() {
var canvas=document.getElementById("myCanvas");
var c=canvas.getContext("2d");
var width = bubble.width;
var volume = bubble.volume;
var centerPoint = bubble.centerPoint;
var height = volume / width;
var halfWidth = width/2;
var halfHeight = height/2;
c.strokeStyle="#002DAF"; // line color
c.fillStyle="#D7FBFF";
c.lineWidth=5; // line width
c.beginPath();
c.moveTo(centerPoint.x,centerPoint.y - halfHeight);
c.quadraticCurveTo(centerPoint.x-halfWidth,
centerPoint.y-halfHeight,centerPoint.x-halfWidth,
centerPoint.y); // top left curve
c.quadraticCurveTo(centerPoint.x-halfWidth,
centerPoint.y+halfHeight,centerPoint.x,
centerPoint.y+halfHeight); // bottom left curve
c.quadraticCurveTo(centerPoint.x+halfWidth,
centerPoint.y+halfHeight,centerPoint.x+halfWidth,
centerPoint.y); // bottom right curve
c.quadraticCurveTo(centerPoint.x+halfWidth,
centerPoint.y-halfHeight,centerPoint.x,
centerPoint.y-halfHeight); // bottom right curve
c.closePath();
c.stroke();
c.fill();
}
function updateStageObjects() {
bubble.oscillate();
}
function clearCanvas() {
context.clearRect(0,0,canvas.width, canvas.height);
}
</script>
</head>
<body onload="init()">
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>
How It Works
To create an oscillating bubble with HTML5 Canvas, we first need to understand the physics behind a bubble’s oscillation. What causes it? When a bubble is first formed – such as the moment you create a soap bubble by blowing into a ring – the bubble is set into motion asymmetrically. In other words, once the bubble’s surface closes as it exits the ring, it will take on an elliptical shape.
The tension forces on the shorter sides of the bubble are not equal to the tension forces on the longer sides of the bubble. As a result, the length of the bubble will begin to retract. Once the bubble has reached a perfect spherical state – the state in which all of the tension forces are equal – the bubble will remain at rest. As the bubble shrinks to fit a spherical shape, it’s momentum causes it to continue expanding in the other direction, causing a continual oscillation.
We can define a bubble based on it’s center point, its width, its volume, and its max tension width. Since the HTML5 canvas API supports quadratic curves, we can define the bubble’s perimeter with four parts – an upper left curve, a lower left curve, a lower right curve, and an upper right curve.
Once we have our bubble, we can oscillate it by increasing the bubble width until a max width has been reached, begin decreasing the width until a minimum width has been reached, and then repeat the cycle.
By Eric Rowell at html5canvastutorials.com
Recent Posts