| class NumberAnimationManager { |
| constructor() { |
| this.container = document.getElementById('animation-container'); |
| this.currentAnimation = null; |
| this.isLooping = false; |
| this.initializeControls(); |
| } |
|
|
| initializeControls() { |
| const playBtn = document.getElementById('play-btn'); |
| const loopToggle = document.getElementById('loop-toggle'); |
| const animationSelect = document.getElementById('animation-select'); |
| const numberSelect = document.getElementById('number-select'); |
|
|
| playBtn.addEventListener('click', () => { |
| this.playAnimation( |
| numberSelect.value, |
| animationSelect.value |
| ); |
| }); |
|
|
| loopToggle.addEventListener('click', () => { |
| this.isLooping = !this.isLooping; |
| loopToggle.textContent = `Loop: ${this.isLooping ? 'On' : 'Off'}`; |
| if (this.isLooping && this.currentAnimation) { |
| this.startLoop(); |
| } |
| }); |
| } |
|
|
| playAnimation(number, animationType) { |
| this.clearContainer(); |
| |
| const numberElement = this.createNumberElement(number); |
| this.container.appendChild(numberElement); |
|
|
| if (animationType === 'smoke') { |
| this.createParticles(); |
| } |
|
|
| |
| setTimeout(() => { |
| numberElement.classList.add(this.getAnimationClass(animationType)); |
| }, 100); |
|
|
| this.currentAnimation = { number, animationType }; |
|
|
| if (this.isLooping) { |
| this.startLoop(); |
| } |
| } |
|
|
| createNumberElement(number) { |
| const div = document.createElement('div'); |
| div.className = 'cinematic-number'; |
| div.textContent = number; |
| div.setAttribute('data-number', number); |
| return div; |
| } |
|
|
| createParticles() { |
| const particlesContainer = document.createElement('div'); |
| particlesContainer.className = 'particles'; |
| |
| for (let i = 0; i < 50; i++) { |
| const particle = document.createElement('div'); |
| particle.className = 'particle'; |
| |
| const angle = Math.random() * Math.PI * 2; |
| const distance = 100 + Math.random() * 200; |
| const tx = Math.cos(angle) * distance; |
| const ty = Math.sin(angle) * distance; |
| |
| particle.style.setProperty('--tx', `${tx}px`); |
| particle.style.setProperty('--ty', `${ty}px`); |
| particle.style.left = '50%'; |
| particle.style.top = '50%'; |
| particle.style.animationDelay = `${Math.random() * 1}s`; |
| |
| particlesContainer.appendChild(particle); |
| } |
| |
| this.container.appendChild(particlesContainer); |
| |
| |
| setTimeout(() => { |
| particlesContainer.remove(); |
| }, 2000); |
| } |
|
|
| getAnimationClass(animationType) { |
| const animationClasses = { |
| 'zoom': 'zoom-in', |
| 'bounce': 'bounce-in', |
| 'smoke': 'smoke-reveal', |
| 'glitch': 'glitch-flicker', |
| 'pulse': 'energy-pulse' |
| }; |
| |
| return animationClasses[animationType] || 'zoom-in'; |
| } |
|
|
| clearContainer() { |
| this.container.innerHTML = ''; |
| } |
|
|
| startLoop() { |
| if (!this.isLooping || !this.currentAnimation) return; |
|
|
| const { number, animationType } = this.currentAnimation; |
| const durations = { |
| 'zoom': 3000, |
| 'bounce': 1500, |
| 'smoke': 4000, |
| 'glitch': 2500, |
| 'pulse': 3000 |
| }; |
|
|
| setInterval(() => { |
| this.playAnimation(number, animationType); |
| }, durations[animationType] || 3000); |
| } |
| } |
|
|
| |
| document.addEventListener('DOMContentLoaded', () => { |
| new NumberAnimationManager(); |
| |
| |
| setTimeout(() => { |
| document.getElementById('play-btn').click(); |
| }, 500); |
| }); |