|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Animated Million Gradio Developers with Fireworks</title> |
|
<style> |
|
body { |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
height: 100vh; |
|
margin: 0; |
|
background: #1a2a6c; |
|
font-family: 'Arial', sans-serif; |
|
overflow: hidden; |
|
position: relative; |
|
} |
|
.container { |
|
text-align: center; |
|
position: relative; |
|
z-index: 10; |
|
} |
|
svg { |
|
max-width: 100%; |
|
height: auto; |
|
} |
|
.text-stroke { |
|
stroke: #fff; |
|
stroke-width: 2; |
|
stroke-dasharray: 1500; |
|
stroke-dashoffset: 1500; |
|
animation: dash 3s linear forwards; |
|
fill: transparent; |
|
font-weight: bold; |
|
font-size: 60px; |
|
} |
|
.counter { |
|
font-size: 80px; |
|
color: white; |
|
font-weight: bold; |
|
margin-bottom: 20px; |
|
} |
|
.firework { |
|
position: absolute; |
|
width: 5px; |
|
height: 5px; |
|
border-radius: 50%; |
|
pointer-events: none; |
|
} |
|
@keyframes dash { |
|
to { |
|
stroke-dashoffset: 0; |
|
fill: white; |
|
} |
|
} |
|
@keyframes firework { |
|
0% { |
|
transform: translate(-50%, -50%) scale(0); |
|
opacity: 1; |
|
} |
|
70% { |
|
opacity: 0.8; |
|
} |
|
100% { |
|
transform: translate(var(--tx), var(--ty)) scale(1); |
|
opacity: 0; |
|
} |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="container"> |
|
<div class="counter" id="counter">0</div> |
|
<svg width="800" height="200" viewBox="0 0 800 200"> |
|
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" class="text-stroke">Gradio Developers</text> |
|
</svg> |
|
</div> |
|
|
|
<script> |
|
|
|
const counter = document.getElementById('counter'); |
|
let count = 0; |
|
const target = 1000000; |
|
const duration = 3000; |
|
const increment = target / (duration / 16); |
|
|
|
function animateCounter() { |
|
if (count < target) { |
|
count += increment; |
|
if (count > target) count = target; |
|
counter.textContent = Math.floor(count).toLocaleString(); |
|
requestAnimationFrame(animateCounter); |
|
if (Math.random() < 0.3) createFirework(); |
|
} else { |
|
|
|
setInterval(createFirework, 300); |
|
} |
|
} |
|
|
|
|
|
function createFirework() { |
|
const firework = document.createElement('div'); |
|
firework.className = 'firework'; |
|
|
|
const x = Math.random() * window.innerWidth; |
|
const y = Math.random() * window.innerHeight; |
|
const color = `hsl(${Math.random() * 60 + 190}, 100%, 50%)`; |
|
|
|
firework.style.left = x + 'px'; |
|
firework.style.top = y + 'px'; |
|
firework.style.backgroundColor = color; |
|
|
|
document.body.appendChild(firework); |
|
|
|
|
|
const particleCount = 30 + Math.floor(Math.random() * 20); |
|
for (let i = 0; i < particleCount; i++) { |
|
createParticle(x, y, color); |
|
} |
|
|
|
setTimeout(() => { |
|
firework.remove(); |
|
}, 1000); |
|
} |
|
|
|
function createParticle(x, y, color) { |
|
const particle = document.createElement('div'); |
|
particle.className = 'firework'; |
|
|
|
const angle = Math.random() * Math.PI * 2; |
|
const radius = 50 + Math.random() * 100; |
|
const size = 2 + Math.random() * 3; |
|
|
|
particle.style.width = size + 'px'; |
|
particle.style.height = size + 'px'; |
|
particle.style.backgroundColor = color; |
|
|
|
particle.style.setProperty('--tx', (Math.cos(angle) * radius) + 'px'); |
|
particle.style.setProperty('--ty', (Math.sin(angle) * radius) + 'px'); |
|
|
|
particle.style.left = x + 'px'; |
|
particle.style.top = y + 'px'; |
|
particle.style.animation = 'firework 0.8s linear forwards'; |
|
|
|
document.body.appendChild(particle); |
|
|
|
setTimeout(() => { |
|
particle.remove(); |
|
}, 800); |
|
} |
|
|
|
|
|
setTimeout(() => { |
|
animateCounter(); |
|
|
|
for (let i = 0; i < 5; i++) { |
|
setTimeout(createFirework, i * 200); |
|
} |
|
}, 500); |
|
|
|
|
|
function resizeText() { |
|
const svg = document.querySelector('svg'); |
|
const newWidth = Math.min(window.innerWidth - 40, 800); |
|
svg.setAttribute('width', newWidth); |
|
} |
|
|
|
window.addEventListener('resize', resizeText); |
|
resizeText(); |
|
</script> |
|
</body> |
|
</html> |