I was really into the āCODEā component, but lately, with the last two updates, itās been super buggy. Iām gonna have to hide it from the app for now. Canāt wait for it to get stable again.
Check out the code and GIF below for more detailsāmake sure to watch till the end!
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>Animated Counter with Styled Progress Bar</title>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"
/>
<style>
body {
font-family: 'Roboto', sans-serif;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
overflow: hidden;
}
.card-container {
perspective: 1000px;
width: 80%;
opacity: 0;
animation: fadeIn 1s ease forwards;
}
.card {
position: relative;
width: 100%;
height: 200px;
transform-style: preserve-3d;
transition: transform 1s;
box-shadow: none;
border-radius: 10px;
}
.front, .back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 20px;
box-sizing: border-box;
border-radius: 10px;
}
.back {
transform: rotateY(180deg);
}
.progress-container {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
margin-bottom: 10px;
}
.progress-label {
font-size: 18px;
color: #ffd700;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
margin-right: 10px;
}
.progress-bar {
height: 10px;
width: calc(100% - 120px);
background-color: #fff;
border-radius: 5px;
position: relative;
overflow: hidden;
}
.progress-fill {
height: 100%;
width: 0%;
background-image: linear-gqradient(to right, #ffd700, #e7c266);
border-radius: 5px;
position: absolute;
top: 0;
left: 0;
transition: width 0.3s ease, background-color 0.3s ease;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16);
}
.counter {
font-size: 36px;
letter-spacing: 2px;
font-variant-numeric: tabular-nums;
color: #ffd700;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
margin-top: 20px;
}
.bottom-text {
font-size: 14px;
color: rgba(255, 255, 255, 0.8);
margin-top: 10px;
}
.title {
font-size: 18px;
color: #ffd700;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
margin-top: 20px;
}
@keyframes slideIn {
0% {
transform: translateX(-100%);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
@keyframes rotate {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(180deg);
}
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>
</head>
<body>
<div class="card-container">
<div class="card" id="card">
<div class="front">
<div class="progress-container">
<div class="progress-label">Inicio</div>
<div class="progress-bar">
<div class="progress-fill"></div>
</div>
<div class="progress-label">Hoje</div>
</div>
<div class="counter">
<span id="counter-number">R$0,00</span>
</div>
</div>
<div class="back">
<div class="counter">
<span id="total-number">R$0,00</span>
</div>
<div class="title">Em negĆ³cios gerados</div>
<div class="bottom-text">Entre maƧons</div>
</div>
</div>
</div>
<script>
const finalValue = 5756226;
const duration = 2000;
const counterElement = document.getElementById(
"counter-number"
);
const totalElement =
document.getElementById("total-number");
const progressBar = document.querySelector(
".progress-fill"
);
const card = document.getElementById("card");
const animateValue = (start, end, duration) => {
const startTime = performance.now();
const updateCounterAndProgress = () => {
const currentTime = performance.now();
const elapsedTime = currentTime - startTime;
if (elapsedTime >= duration) {
counterElement.textContent =
formatCurrency(end);
progressBar.style.width = "100%";
card.style.animation = "rotate 1s forwards";
totalElement.textContent = formatCurrency(end);
} else {
const progress = (elapsedTime / duration) * 100;
progressBar.style.width = `${progress}%`;
counterElement.textContent = formatCurrency(
start +
Math.floor(
(end - start) * (elapsedTime / duration)
)
);
progressBar.style.backgroundImage = `linear-gradient(to right, #ffd700, #e7c266)`;
requestAnimationFrame(updateCounterAndProgress);
}
};
requestAnimationFrame(updateCounterAndProgress);
};
const formatCurrency = (value) => {
return value.toLocaleString("pt-BR", {
style: "currency",
currency: "BRL",
});
};
// Inicia a animaĆ§Ć£o imediatamente
animateValue(0, finalValue, duration);
</script>
</body>
</html>