Open In App

Chandelier Animation Using Typescript

Last Updated : 04 Feb, 2025
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

In this project, we'll create an interactive chandelier animation that moves in response to mouse movements. Using Euclidean formulas, we'll calculate distances between nodes to ensure smooth and realistic motion.

What We’re Going to Create

In this project, we will create an interactive chandelier animation using HTML, CSS, and TypeScript.

  • In this, we will make a canvas board.
  • We will create a canvas line and after that, we will make canvas circles.
  • In this, we will add certain class concepts by which we could tackle the chandelier with mouse movements.

Project Preview

Screenshot-2025-01-27-174330
Chandelier using Typescript

Chandelier Animation- HTML and CSS code

The following HTML code sets up a full-page canvas inside the body for rendering an interactive animation. The CSS code is then integrated with HTML to style the circles and lines.

<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        html, body {
            height: 100%;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #191919;
        }
        #c{
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="c"></canvas>
</body>
</html>

In this example

  • The <canvas> element is used to create a drawable area on the webpage where graphics can be rendered dynamically using JavaScript.
  • The <head> and <body> tags structure the webpage, with the canvas inside the body. The head contains the <style> tag, where CSS can be applied to the page.
  • The canvas will expand to fill the entire page, allowing for full-screen visual effects, animations, or interactive elements.

Chandelier Animation -TypeScript Logic

The TypeScript code creates an interactive animation of particles that respond to mouse movement, simulating a chandelier effect on the canvas. It uses object-oriented programming by defining a Particle class and uses HTML5's canvas API to render and animate the particles.

const c = document.getElementById('c') as HTMLCanvasElement;
const ctx = c.getContext('2d');
let p: Particle[] = [];
let pc = 500;
let m = { x: null as number | null, y: null as number | null };

function resize(): void {
    c.width = window.innerWidth;
    c.height = window.innerHeight;
    p.length = 0;
    init();
}

class Particle {
    ax: number;
    ay: number = 0;
    x: number;
    y: number;
    baseY: number;
    r: number;
    o: number;
    swing: number;
    constructor(ax: number) {
        this.ax = ax;
        this.x = ax;
        this.y = Math.random() * (c.height / 2) + 50;
        this.baseY = this.y;
        this.r = Math.random() * 3 + 2;
        this.o = Math.random() * 0.5 + 0.5;
        this.swing = Math.random() * 0.1 + 0.05;
    }
    update(): void {
        const dx = (m.x as number) - this.x;
        const dy = (m.y as number) - this.y;
        const dist = Math.sqrt(dx * dx + dy * dy);
        if (dist < 150) {
            this.x += dx * 0.03;
            this.y += dy * 0.03;
        } else {
            this.x += (this.ax - this.x) * this.swing;
            this.y += (this.baseY - this.y) * this.swing;
        }
    }
    draw(): void {
        ctx.beginPath();
        ctx.moveTo(this.ax, this.ay);
        ctx.lineTo(this.x, this.y);
        ctx.lineWidth = 1;
        ctx.strokeStyle = `rgba(255, 215, 0, 0.3)`;
        ctx.stroke();
        ctx.closePath();
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
        ctx.fillStyle = `rgba(255,255,255,${this.o})`;
        ctx.fill();
        ctx.closePath();
    }
}

function init(): void {
    for (let i = 0; i < pc; i++) {
        const ax = Math.random() * c.width;
        p.push(new Particle(ax));
    }
}

function animate(): void {
    ctx.clearRect(0, 0, c.width, c.height);
    p.forEach((particle) => {
        particle.update();
        particle.draw();
    });
    requestAnimationFrame(animate);
}

window.addEventListener('mousemove', function (e: MouseEvent): void {
    m.x = e.clientX;
    m.y = e.clientY;
});

window.addEventListener('resize', resize);
window.addEventListener('load', resize);

animate();

In this example

  • Accesses the canvas and its 2D context (ctx) for drawing and animation.
  • Models particles with random properties like position, size, and movement behavior, responding to the mouse.
  • Moves particles towards the mouse within 150px or swings them back to their anchor position.
  • Continuously updates and redraws particles using requestAnimationFrame() for smooth animation and resizes the canvas on window changes.

Convert to JavaScript File

Now You need to convert the TypeScript file into JavaScript to render by browser. Use one of the following command.

npx  tsc type.ts
tsc type.ts
  • The command type.ts compiles the type.ts TypeScript file into a type.js JavaScript file.
  • It places the output in the same directory as the input file by default.

Complete Code

<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            height: 100vh;
        }
        html,
        body {
            height: 100%;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #191919;
        }
        c {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="c"></canvas>
    <script defer>
        const c = document.getElementById('c');
        const ctx = c.getContext('2d');
        let p = [];
        let pc = 500;
        let m = { x: null, y: null };
        function resize() {
            c.width = window.innerWidth;
            c.height = window.innerHeight;
            p.length = 0;
            init();
        }
        class Particle {
            constructor(ax) {
                this.ax = ax;
                this.ay = 0;
                this.x = ax;
                this.y = Math.random() * (c.height / 2) + 50;
                this.baseY = this.y;
                this.r = Math.random() * 3 + 2;
                this.o = Math.random() * 0.5 + 0.5;
                this.swing = Math.random() * 0.1 + 0.05;
            }
            update() {
                const dx = m.x - this.x;
                const dy = m.y - this.y;
                const dist = Math.sqrt(dx * dx + dy * dy);
                if (dist < 150) {
                    this.x += dx * 0.03;
                    this.y += dy * 0.03;
                } else {
                    this.x += (this.ax - this.x) * this.swing;
                    this.y += (this.baseY - this.y) * this.swing;
                }
            }
            draw() {
                ctx.beginPath();
                ctx.moveTo(this.ax, this.ay);
                ctx.lineTo(this.x, this.y);
                ctx.lineWidth = 1;
                ctx.strokeStyle = `rgba(255, 215, 0, 0.3)`;
                ctx.stroke();
                ctx.closePath();
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
                ctx.fillStyle = `rgba(255,255,255,${this.o})`;
                ctx.fill();
                ctx.closePath();
            }
        }
        function init() {
            for (let i = 0; i < pc; i++) {
                const ax = Math.random() * c.width;
                p.push(new Particle(ax));
            }
        }
        function animate() {
            ctx.clearRect(0, 0, c.width, c.height);
            p.forEach((particle) => {
                particle.update();
                particle.draw();
            });
            requestAnimationFrame(animate);
        }
        window.addEventListener('mousemove', function (e) {
            m.x = e.clientX;
            m.y = e.clientY;
        });
        window.addEventListener('resize', resize);
        window.addEventListener('load', resize);
        animate();
    </script>
</body>
</html>

Similar Reads

three90RightbarBannerImg