Coffee Animation with JavaScript's Canvas API
If you aren't seeing the animation above, please make sure JavaScript is enabled.
I created this small animation for my Computer Graphics class. At the time, we were learning about transformations such as translation, scale, rotation, etc. I decided to do an animation of coffee being poured into a cup and steam coming out of the cup. Although I used the built in transformations in Canvas, we did go over the math behind the transformations. Having already taken Linear Algebra prior, I was quite familiar with this topic. Anyways, this was one of my first assignments and I really loved the combination of math and programming together!
JavaScript code below!
// ------- variables -------
var canvas; // DOM object corresponding to the canvas
var graphics; // 2D graphics context for drawing on the canvas
var backgroundColor = "rgba(255, 153, 153, 255)";
var tableColor = "rgba(204, 229, 255, 255)";
var cupColor = "rgba(224, 224, 224, 255)";
var drinkColor = "rgba(102, 50, 0, 255)";
var timer = 0;
// --------- constructors ------------
// creates a filled rectangle
function Rectangle(x,y,h,w,color,s) {
this.x = x; // x coord
this.y = y; // y coord
this.h = h; // height
this.w = w; // width
this.s = s; // scale factor
this.color = color; // fill color
// renders rectangle
this.draw = function draw(graphics) {
graphics.fillStyle = this.color;
graphics.fillRect(0,0,this.w,this.h);
}
// renders rectangle
this.render= function start() {
graphics.save();
graphics.translate(this.x,this.y);
graphics.scale(1,this.s);
this.draw(graphics);
graphics.restore();
}
// updates stream size
this.update = function update() {
// increases stream's height
if (this.s < 200) {
this.s *= s;
}
}
}
// creates a colored cup
function Cup(x,y,h,w,color) {
this.x = x; // x coord
this.y = y; // y coord
this.h = h; // height
this.w = w; // width
this.color = color; // color of cup
this.draw = function draw(graphics) { // draws cup and colors it
graphics.beginPath();
graphics.moveTo(this.x, this.y);
graphics.lineTo(this.x+(this.w/2), this.y);
graphics.lineTo(this.x+(3*this.w/4), this.y - this.h);
graphics.lineTo(this.x-(this.w/4), this.y - this.h);
graphics.fillStyle = this.color;
graphics.fill();
}
}
// creates the smoke puff
function Smoke(x,y,dx){
this.x = x; // the x coord of center
this.y = y; // the y coord of center
this.s = 1; // scale factor
this.dx = dx; // the change of x pos
this.alpha = 80; // transparency val
this.color = `rgb(255 255 255 / ${this.alpha}%)`; // the transparency of the smoke puff
// draws smoke puff
this.draw = function drawT(graphics) {
graphics.beginPath();
graphics.arc(0,0,18,0,2*Math.PI);
graphics.fillStyle = this.color;
graphics.fill();
}
// renders the smoke puff
this.render = function render() {
graphics.save();
graphics.translate(this.x, this.y);
graphics.scale(this.s, this.s);
this.draw(graphics);
graphics.restore();
}
// updates the transformation
this.update = function updateT() {
// makes smoke puff got left to right and right to left randomly
if (timer < 20) {
this.x += this.dx;
} else {
this.x -= this.dx;
}
timer++;
timer %= 40;
// updates y pos
this.y -= 1;
// updates scale factor relative to y pos
this.s = (this.y - 67)/100;
// decreases transparency
this.alpha *= (this.y - 67)/100;
// if scale is 0, then reset smoke puff
if (this.s < 0) {
this.reset();
}
}
// resets the positon of smoke puff
this.reset = function reset() {
this.x = x; // the x coord of center
this.y = y; // the y coord of center
this.dx = -dx; // the change of x coord
this.s = 1; // scale factor
this.alpha = 80; // transparency
this.color = `rgb(255 255 255 / ${this.alpha}%)`; // the transparency of the smoke puff
}
}
// ------- objects ---------
// background
var background = new Rectangle(0,0,250, 450, backgroundColor, 1);
// table
var table = new Rectangle(0,250,50, 450, tableColor, 1);
// smoke puffs
var smokePuffs = [];
smokePuffs.push(new Smoke(225, 167, 1));
smokePuffs.push(new Smoke(248, 170, 0));
smokePuffs.push(new Smoke(205, 180, 1));
smokePuffs.push(new Smoke(200, 200, 0));
smokePuffs.push(new Smoke(226, 170, 0));
smokePuffs.push(new Smoke(220, 220, 1));
smokePuffs.push(new Smoke(205, 190, 0));
// cup
var coffeeCup = new Cup(190, 250, 114, 150, cupColor);
// coffee stream
var coffee = new Rectangle(220,10,1,10, drinkColor, 1.09);
// the output of coffee stream
var coffeeMaker = new Rectangle(210,0,10,30, tableColor, 1);
// timer for smoke puff positions
var timer = 0;
// ------- animate ----------
function animate() {
// -------prep canvas--------
// render background
background.render();
table.render();
coffeeMaker.render();
// ----- setting up transformations ----
// renders coffee stream
coffee.render();
// renders smoke puffs
for (p in smokePuffs){
smokePuffs[p].render();
}
//renders cup
coffeeCup.draw(graphics);
for (p in smokePuffs){
smokePuffs[p].update();
}
coffee.update();
}
function test() {
canvas = document.getElementById("theCanvas");
graphics = canvas.getContext("2d");
setInterval(animate,30);
}