← back to Goodquestion Ai
video-html/slides/sample-big-number.html
184 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1920, height=1080">
<title>Numbers</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: 1920px;
height: 1080px;
overflow: hidden;
background: #0B0B0F;
color: #E8E8ED;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
-webkit-font-smoothing: antialiased;
}
.slide {
width: 1920px;
height: 1080px;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
}
/* Animations */
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes growWidth {
from { width: 0; }
}
@keyframes gradientShift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
@keyframes pulseGlow {
0%, 100% { text-shadow: 0 0 20px rgba(0,212,255,0.3); }
50% { text-shadow: 0 0 40px rgba(0,212,255,0.6), 0 0 80px rgba(0,212,255,0.2); }
}
@keyframes slideInLeft {
from { opacity: 0; transform: translateX(-40px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes avatarFadeIn {
0% { opacity: 0; transform: scale(0.8); }
15% { opacity: 1; transform: scale(1); }
85% { opacity: 1; transform: scale(1); }
100% { opacity: 0; transform: scale(0.9); }
}
.avatar-container {
position: absolute;
bottom: 40px;
right: 40px;
width: 200px;
height: 200px;
border-radius: 50%;
overflow: hidden;
border: 3px solid #00D4FF;
box-shadow: 0 0 30px rgba(0,212,255,0.3);
animation: avatarFadeIn 3s ease-in-out forwards;
z-index: 100;
}
.avatar-container img {
width: 100%;
height: 100%;
object-fit: cover;
}
.slide-numbers {
background: radial-gradient(ellipse at 50% 50%, #111827 0%, #0B0B0F 70%);
}
.numbers-row {
display: flex;
align-items: center;
justify-content: center;
gap: 100px;
flex-wrap: wrap;
}
.number-card {
display: flex;
flex-direction: column;
align-items: center;
opacity: 0;
animation: fadeInUp 0.8s ease-out both;
}
.number-card:nth-child(1) { animation-delay: 0.3s; }
.number-card:nth-child(2) { animation-delay: 0.6s; }
.number-card:nth-child(3) { animation-delay: 0.8999999999999999s; }
.number-value {
font-size: 96px;
font-weight: 900;
font-variant-numeric: tabular-nums;
line-height: 1;
}
.number-label {
font-size: 24px;
color: #6B7280;
margin-top: 12px;
text-transform: uppercase;
letter-spacing: 2px;
}
.number-bar {
width: 80px;
height: 4px;
border-radius: 2px;
margin-top: 16px;
animation: growWidth 0.6s ease-out both;
}
.number-card:nth-child(1) .number-bar { animation-delay: 0.8s; }
.number-card:nth-child(2) .number-bar { animation-delay: 1.1s; }
.number-card:nth-child(3) .number-bar { animation-delay: 1.4s; }
</style>
</head>
<body>
<div class="slide slide-numbers">
<div class="numbers-row">
<div class="number-card">
<div class="number-value" style="color: #00D4FF;">
<span class="counter" data-target="122" data-prefix="" data-suffix="">0</span>
</div>
<div class="number-label">Products Processed</div>
<div class="number-bar" style="background: #00D4FF;"></div>
</div>
<div class="number-card">
<div class="number-value" style="color: #FF6B35;">
<span class="counter" data-target="566" data-prefix="" data-suffix="">0</span>
</div>
<div class="number-label">Data Points Set</div>
<div class="number-bar" style="background: #FF6B35;"></div>
</div>
<div class="number-card">
<div class="number-value" style="color: #00E68C;">
<span class="counter" data-target="100" data-prefix="" data-suffix="%">0%</span>
</div>
<div class="number-label">Coverage</div>
<div class="number-bar" style="background: #00E68C;"></div>
</div>
</div>
</div>
<script>
function animateCounters() {
document.querySelectorAll('.counter').forEach(el => {
const target = parseInt(el.dataset.target, 10);
const prefix = el.dataset.prefix || '';
const suffix = el.dataset.suffix || '';
const duration = 1500;
const start = performance.now();
function update(now) {
const elapsed = now - start;
const progress = Math.min(elapsed / duration, 1);
// Ease-out cubic
const eased = 1 - Math.pow(1 - progress, 3);
const current = Math.round(eased * target);
el.textContent = prefix + current.toLocaleString() + suffix;
if (progress < 1) requestAnimationFrame(update);
}
// Delay start to match fade-in
setTimeout(() => requestAnimationFrame(update), 600);
});
}
window.addEventListener('load', animateCounters);
</script>
</body>
</html>