JSFiddle - React, Tailwind, and code Playground
by Mladen Mihajlovic
HTML
<canvas id="odometer" width="200" height="60"></canvas>
JavaScript
const canvas = document.getElementById('odometer');
const ctx = canvas.getContext('2d');
// Set starting and ending numbers
let startNumber = 0;
let endNumber = 100;
// Set animation duration
const animationDuration = 10000; // 10 seconds
// Set animation start time
let animationStartTime;
// Set font style
ctx.font = 'bold 50px Arial';
// Function to update the odometer value
function updateOdometer(timestamp) {
if (!animationStartTime) {
animationStartTime = timestamp;
}
const progress = timestamp - animationStartTime;
const percentage = Math.min(progress / animationDuration, 1);
const currentNumber = Math.round(startNumber + percentage * (endNumber - startNumber));
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw each digit
const digitWidth = 50;
const digitHeight = 50;
let x = (canvas.width - digitWidth * currentNumber.toString().length) / 2;
let y = (canvas.height - digitHeight) / 2;
currentNumber
.toString()
.split('')
.forEach((digit, i) => {
const digitY = parseInt(digit) * digitHeight;
ctx.drawImage(
odometerDigits,
i * 50,
digitY,
odometerDigits.width,
digitHeight,
x,
y,
digitWidth,
digitHeight
);
y += digitHeight;
});
if (percentage < 1) {
requestAnimationFrame(updateOdometer);
}
}
// Load digit images
const odometerDigits = new Image();
odometerDigits.src = 'https://iili.io/HwKu1SI.png';
odometerDigits.onload = () => {
requestAnimationFrame(updateOdometer);
};