JSFiddle - React, Tailwind, and code Playground

by Mladen Mihajlovic

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Odometer Animation</title>
    <style>
        canvas {
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <canvas id="odometer" width="200" height="50"></canvas>
    <script>
        class Odometer {
            constructor(canvas, startValue, endValue, duration) {
                this.canvas = canvas;
                this.ctx = canvas.getContext('2d');
                this.startValue = startValue;
                this.endValue = endValue;
                this.currentValue = startValue;
                this.duration = duration;
                this.startTime = null;
            }

            animate(timestamp) {
                if (!this.startTime) {
                    this.startTime = timestamp;
                }

                const elapsed = timestamp - this.startTime;
                const progress = Math.min(elapsed / this.duration, 1);
                this.currentValue = this.startValue + (this.endValue - this.startValue) * progress;

                this.draw(progress);

                if (progress < 1) {
                    requestAnimationFrame((timestamp) => this.animate(timestamp));
                }
            }

            draw(progress) {
                this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

                this.ctx.font = '30px Arial';
                this.ctx.textAlign = 'center';
                this.ctx.textBaseline = 'middle';

                const currentDigits = this.currentValue.toFixed(0).split('');
                const startX = this.canvas.width / 2 - (currentDigits.length * 15);

                currentDigits.forEach((digit, index) => {
                    const currentValue = parseInt(digit);
                    const nextValue = (currentValue + 1) % 10;
                    const digitProgress = this.currentValue % 1;

   ...