Simple Elliptical Animation with Canvas in JavaScript

thumbnail

Hello Guys, In this tutorial, we’ll explore how to create a simple animation using JavaScript and HTML5 Canvas using ellipse and circle. Specifically, we’ll focus on drawing ellipses and animating circles around them.

Prerequisites

Before we start, make sure you have a basic understanding of HTML and JavaScript.

To get more details on Canvas refer to the below docs

Canvas API - Web APIs | MDN

Create an HTML file and include a canvas element in the body.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Elliptical Animation</title>
    <style>
        *{
          margin:0;
          padding:0;
          box-sizing:border-box;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="800" height="600"></canvas>
    <script src="app.js"></script>
</body>
</html>

Setting up the Canvas

In your JavaScript file (app.js), get the canvas context, and set its width and height. Define variables for the canvas dimensions, center coordinates, ellipse radius, initial angle, and an array of objects containing properties(speed and rotate angle) of ellipses path.

// app.js

const canvas = document.querySelector("#canvas");
const ctx = canvas.getContext("2d");

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let CANVAS_WIDTH = canvas.width;
let CANVAS_HEIGHT = canvas.height;
let centerX = CANVAS_WIDTH / 2;
let centerY = CANVAS_HEIGHT / 2;
let radiusX = 100;
let radiusY = 50;
let angle = 0;
const ellipses = [
    { speed: 0.0009, rotateAngle: Math.PI / 4 },
    { speed: 0.00045, rotateAngle: Math.PI / 2 },
    { speed: 0.0009, rotateAngle: -Math.PI / 4 },
    { speed: 0.00045, rotateAngle: Math.PI },
];

Drawing Ellipses and Circles

Now, let’s create a draw function to clear the canvas and draw ellipses with rotating circles around them.

...
function draw() {
    ctx.fillStyle = "#000111"
    ctx.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
    ellipses.forEach((ellipse) => {
        ctx.translate(centerX, centerY);
        ctx.rotate(ellipse.rotateAngle);
        // Draw the ellipse
        ctx.lineWidth = 2;
        ctx.strokeStyle = "#ddd";
        ctx.beginPath();
        ctx.ellipse(0, 0, radiusX, radiusY, 0, 0, 2 * Math.PI);
        ctx.stroke();
        // Calculate circle position based on time
        const currentAngle = Date.now() * ellipse.speed;
        const circleX = radiusX * Math.cos(currentAngle);
        const circleY = radiusY * Math.sin(currentAngle);
        // Draw the rotating circle
        ctx.beginPath();
        ctx.arc(circleX, circleY, 10, 0, 2 * Math.PI);
        ctx.fillStyle = 'blue';
        ctx.fill();
        // Reset transformations
        ctx.setTransform(1, 0, 0, 1, 0, 0);
    });
    requestAnimationFrame(draw);
}
draw();

First, fill the entire canvas with some background color I am using #000111, and after that loop over the ellipses array to display and animate.

ctx.translate brings the canvas context origin to to center of the canvas, such that an ellipse will be drawn from the center.

ctx.rotate rotates the ellipse based on the angle provided.

ctx.lineWidth sets the width of the stroke it's like a border width. ctx.strokeStylesets the color of the stroke it's like a border color.ctx.beginPath & ctx.ellipse draws the ellipse with the parameters below.

  • (0, 0): The center coordinates of the ellipse (x, y).
  • radiusX: The horizontal radius of the ellipse.
  • radiusY: The vertical radius of the ellipse.
  • 0: The rotation of the ellipse (in radians). Here, it's set to 0, meaning no rotation.
  • 0: The starting angle of the ellipse in radians.
  • 2 * Math.PI: The ending angle of the ellipse in radians, representing a complete ellipse (360 degrees).

ctx.stroke(): This draws the outline of the ellipse using the current line width and stroke style. It completes the path and renders the ellipse on the canvas.

Next, we calculate the current angle based on the current timestamp (Date.now()) multiplied by the speed of the ellipse (ellipse.speed). This produces a continuously changing angle, creating the effect of rotation over time. To calculate we use trigonometry functions sine and cosine, reason for using this is sine helps in calculating the y-coordinate, and cosine helps in calculating the x-coordinate, which we multiply with radius to animate. Next, we will use the arc function to draw the circle with the calculated x and y, with fill style resulting in a solid blue circle.

ctx.setTransformThis line resets all transformations applied to the canvas, effectively clearing any translations or rotations. It ensures that subsequent drawings are not affected by the transformations applied within this ellipse.

Finally, requestAnimationFramerequests the browser to call the draw function for the next animation frame.

Now you can view your html file in the browser.

Congratulations! You’ve successfully created an animated scene with ellipses and rotating circles using HTML5 Canvas and JavaScript. Feel free to tweak the parameters and explore more complex animations. Happy coding!