Skip to content

Instantly share code, notes, and snippets.

@kebman
Created May 27, 2018 04:00
Show Gist options
  • Save kebman/22536c75e020fff0cecaf0abdf14527b to your computer and use it in GitHub Desktop.
Save kebman/22536c75e020fff0cecaf0abdf14527b to your computer and use it in GitHub Desktop.
Small Animation Logic Tutorial for JavaScript Canvas
<!DOCTYPE html>
<html>
<head>
<title>Animation Logic Tutorial for Canvas</title>
<meta charset="utf-8">
<style type="text/css">
canvas {
background-color: #ddd;
/* so the canvas can be seen... */
}
</style>
</head>
<body>
<header>
<h1>Canvas Tutorial</h1>
</header>
<section>
<article>
<h1>Animation Logic</h1>
<canvas id="canvas"></canvas>
</article>
<article>
<p id="info"></p>
</article>
</section>
<footer>
</footer>
</body>
</html>
<script type="text/javascript">
// get the canvas and the p-element used to publish info
const canvas = document.getElementById("canvas");
const info = document.getElementById("info");
canvas.width = 600;
const PHI = (1 + Math.sqrt(5)) / 2; // colden ratio
canvas.height = canvas.width/PHI // golden ratio size canvas
// call the JavaScript animation API
const ctx = canvas.getContext("2d");
// declare a constructor object for the balls
function ball(x, y, r, color) {
this.color = color;
if (color === undefined) {
this.color = "Red";
}
this.x = x; // starting x pos
this.y = y; // starting y pos
this.r = r; // radius
this.vx = this.x; // velocity of x
this.vy = this.y; // velocity of y
this.draw = function() {
ctx.beginPath();
ctx.arc(this.vx, this.vy, this.r, 0, 2*Math.PI);
ctx.lineWidth = 5;
ctx.stroke();
ctx.fillStyle = this.color;
ctx.fill();
}
}
// initiate a couple of objects
// that will later be animated
const circle1 = new ball(35, 100, 15);
const circle2 = new ball(50, 200, 15, "White");
// initiate a counter
let i = 0;
// declare a function that repeats itsef
function animate() {
// make a function handle, so the function can be stopped
// and make requestiAnimationFrame repeatedly call animate() until the handle is unloaded
let anihandle = requestAnimationFrame(animate);
// clear the drawing before the scene is re-drawn
// ...otherwise it would look like a stroke
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw a couple of balls...
circle1.draw();
circle2.draw();
// ...and animate them
circle1.vx = circle1.x + i;
circle2.vx = circle1.x + i*(i/200); // x^2 accelleration just for fun
// but stop the object anim when it's beyond the screen width
if (circle2.vx >= canvas.width+15) {
circle2.vx = canvas.width+15;
}
if (circle1.vx >= canvas.width+15) {
circle1.vx = canvas.width+15;
}
// increase i by 1 for each repetition of animate()
// so that it can be used to animate stuff...
i++;
// cancel animation when it reaches a limit
// also make sure the limit is a little bigger then the actial canvas
// and when nothing more happens in the screen
if (i-35 >= canvas.width) {
cancelAnimationFrame(anihandle);
}
// notice: Limit only needed in the +x axis for this project
// since the balls are only moving in the +x direction
// a more elaborate setup would be needed for balls moving in all directions
// print the count so we know the function works
info.innerHTML = i;
}
// run the animation
animate();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment