UNPKG

my-animation-lib

Version:

A powerful animation library combining Three.js, GSAP, custom scroll triggers, and advanced effects with MathUtils integration

665 lines (571 loc) 24.3 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Advanced Effects Demo - My Animation Library</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Arial', sans-serif; line-height: 1.6; color: #333; background: #f0f0f0; } .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; padding: 3rem 2rem; position: relative; overflow: hidden; } .header h1 { font-size: 3rem; margin-bottom: 1rem; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); } .header p { font-size: 1.2rem; opacity: 0.9; } .floating-elements { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } .floating-element { position: absolute; width: 50px; height: 50px; background: rgba(255, 255, 255, 0.1); border-radius: 50%; animation: float 6s ease-in-out infinite; } .floating-element:nth-child(1) { top: 20%; left: 10%; animation-delay: 0s; } .floating-element:nth-child(2) { top: 60%; right: 15%; animation-delay: 2s; } .floating-element:nth-child(3) { top: 40%; left: 80%; animation-delay: 4s; } @keyframes float { 0%, 100% { transform: translateY(0px) rotate(0deg); } 50% { transform: translateY(-20px) rotate(180deg); } } .container { max-width: 1200px; margin: 0 auto; padding: 2rem; } .section { margin-bottom: 4rem; padding: 2rem; background: white; border-radius: 15px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); } .section h2 { font-size: 2.5rem; margin-bottom: 1.5rem; color: #333; text-align: center; } .effects-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 2rem; margin-top: 2rem; } .effect-card { background: #f8f9fa; padding: 1.5rem; border-radius: 10px; border: 2px solid transparent; transition: all 0.3s ease; cursor: pointer; } .effect-card:hover { border-color: #667eea; transform: translateY(-5px); box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1); } .effect-card h3 { color: #667eea; margin-bottom: 1rem; font-size: 1.3rem; } .effect-card p { color: #666; margin-bottom: 1rem; } .effect-demo { min-height: 100px; display: flex; align-items: center; justify-content: center; background: white; border-radius: 8px; margin-bottom: 1rem; border: 1px solid #ddd; } .text-effect-demo { font-size: 1.5rem; font-weight: bold; color: #333; } .image-effect-demo { width: 100px; height: 100px; background: linear-gradient(45deg, #667eea, #764ba2); border-radius: 10px; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; } .controls { background: #333; color: white; padding: 2rem; border-radius: 15px; margin-bottom: 2rem; } .controls h3 { color: #00ff88; margin-bottom: 1rem; } .control-group { margin-bottom: 1rem; } .control-group label { display: block; margin-bottom: 0.5rem; font-size: 0.9rem; } .control-group input, .control-group select, .control-group button { width: 100%; padding: 0.5rem; margin-bottom: 0.5rem; border: none; border-radius: 5px; background: #555; color: white; } .control-group button { background: #007bff; cursor: pointer; transition: background 0.3s; } .control-group button:hover { background: #0056b3; } .control-group button.active { background: #28a745; } .button-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem; } .performance { background: #f8f9fa; padding: 1rem; border-radius: 10px; margin-top: 1rem; font-family: monospace; font-size: 0.9rem; } .performance div { margin-bottom: 0.5rem; } .footer { background: #333; color: white; text-align: center; padding: 2rem; margin-top: 4rem; } @media (max-width: 768px) { .header h1 { font-size: 2rem; } .effects-grid { grid-template-columns: 1fr; } .button-grid { grid-template-columns: 1fr; } } </style> </head> <body> <div class="header"> <div class="floating-elements"> <div class="floating-element"></div> <div class="floating-element"></div> <div class="floating-element"></div> </div> <h1>Advanced Effects Demo</h1> <p>Experience the full power of our animation library</p> </div> <div class="container"> <div class="controls"> <h3>Global Controls</h3> <div class="control-group"> <label>Animation Speed:</label> <input type="range" id="globalSpeed" min="0.1" max="3" value="1" step="0.1"> <span id="speedValue">1x</span> </div> <div class="control-group"> <button id="pauseAll">Pause All</button> <button id="resumeAll">Resume All</button> <button id="resetAll">Reset All</button> </div> </div> <div class="section"> <h2>Text Effects</h2> <div class="effects-grid"> <div class="effect-card" data-effect="typewriter"> <h3>Typewriter</h3> <p>Text appears character by character</p> <div class="effect-demo"> <div class="text-effect-demo" id="typewriter-demo">Hello World!</div> </div> <button class="play-effect">Play Effect</button> </div> <div class="effect-card" data-effect="scramble"> <h3>Scramble</h3> <p>Text scrambles and reveals</p> <div class="effect-demo"> <div class="text-effect-demo" id="scramble-demo">Scramble Text</div> </div> <button class="play-effect">Play Effect</button> </div> <div class="effect-card" data-effect="wave"> <h3>Wave</h3> <p>Text waves like water</p> <div class="effect-demo"> <div class="text-effect-demo" id="wave-demo">Wave Effect</div> </div> <button class="play-effect">Play Effect</button> </div> <div class="effect-card" data-effect="bounce"> <h3>Bounce</h3> <p>Text bounces with energy</p> <div class="effect-demo"> <div class="text-effect-demo" id="bounce-demo">Bounce!</div> </div> <button class="play-effect">Play Effect</button> </div> <div class="effect-card" data-effect="glitch"> <h3>Glitch</h3> <p>Digital glitch effect</p> <div class="effect-demo"> <div class="text-effect-demo" id="glitch-demo">Glitch</div> </div> <button class="play-effect">Play Effect</button> </div> <div class="effect-card" data-effect="slideIn"> <h3>Slide In</h3> <p>Text slides in from sides</p> <div class="effect-demo"> <div class="text-effect-demo" id="slideIn-demo">Slide In</div> </div> <button class="play-effect">Play Effect</button> </div> </div> </div> <div class="section"> <h2>Image Effects</h2> <div class="effects-grid"> <div class="effect-card" data-effect="morph"> <h3>Morph</h3> <p>Shape-shifting transformation</p> <div class="effect-demo"> <div class="image-effect-demo" id="morph-demo">Morph</div> </div> <button class="play-effect">Play Effect</button> </div> <div class="effect-card" data-effect="distortion"> <h3>Distortion</h3> <p>Wave-like distortion</p> <div class="effect-demo"> <div class="image-effect-demo" id="distortion-demo">Distort</div> </div> <button class="play-effect">Play Effect</button> </div> <div class="effect-card" data-effect="glitch"> <h3>Glitch</h3> <p>Digital corruption effect</p> <div class="effect-demo"> <div class="image-effect-demo" id="glitch-img-demo">Glitch</div> </div> <button class="play-effect">Play Effect</button> </div> <div class="effect-card" data-effect="wave"> <h3>Wave</h3> <p>Ocean wave movement</p> <div class="effect-demo"> <div class="image-effect-demo" id="wave-img-demo">Wave</div> </div> <button class="play-effect">Play Effect</button> </div> <div class="effect-card" data-effect="pulse"> <h3>Pulse</h3> <p>Heartbeat rhythm</p> <div class="effect-demo"> <div class="image-effect-demo" id="pulse-demo">Pulse</div> </div> <button class="play-effect">Play Effect</button> </div> <div class="effect-card" data-effect="shake"> <h3>Shake</h3> <p>Earthquake effect</p> <div class="effect-demo"> <div class="image-effect-demo" id="shake-demo">Shake</div> </div> <button class="play-effect">Play Effect</button> </div> </div> </div> <div class="section"> <h2>Combined Effects</h2> <div class="effects-grid"> <div class="effect-card"> <h3>Text + Image Combo</h3> <p>Multiple effects simultaneously</p> <div class="effect-demo"> <div class="text-effect-demo" id="combo-text">Combo</div> <div class="image-effect-demo" id="combo-img" style="margin-left: 1rem;">FX</div> </div> <button id="playCombo">Play Combo</button> </div> <div class="effect-card"> <h3>Sequence Chain</h3> <p>Effects play in sequence</p> <div class="effect-demo"> <div class="text-effect-demo" id="sequence-demo">Sequence</div> </div> <button id="playSequence">Play Sequence</button> </div> <div class="effect-card"> <h3>Random Effects</h3> <p>Random effect selection</p> <div class="effect-demo"> <div class="text-effect-demo" id="random-demo">Random</div> </div> <button id="playRandom">Play Random</button> </div> </div> </div> <div class="performance"> <h4>Performance Monitor</h4> <div>Active Effects: <span id="activeEffects">0</span></div> <div>FPS: <span id="fps">0</span></div> <div>Memory: <span id="memory">0</span> MB</div> </div> </div> <div class="footer"> <p>&copy; 2024 My Animation Library. All rights reserved.</p> </div> <script type="module"> import { AnimationEngine, TextEffects, ImageEffects } from '../src/index.js'; // Initialize the animation engine const engine = new AnimationEngine(); await engine.init(); // Initialize effects classes const textEffects = new TextEffects(); const imageEffects = new ImageEffects(); // Global state let globalSpeed = 1; let isPaused = false; let activeEffects = 0; let currentAnimations = new Map(); // Performance monitoring let frameCount = 0; let lastTime = performance.now(); let fps = 0; function updatePerformance() { frameCount++; const currentTime = performance.now(); if (currentTime - lastTime >= 1000) { fps = Math.round((frameCount * 1000) / (currentTime - lastTime)); document.getElementById('fps').textContent = fps; // Memory usage (approximate) if (performance.memory) { const memoryMB = Math.round(performance.memory.usedJSHeapSize / 1024 / 1024); document.getElementById('memory').textContent = memoryMB; } frameCount = 0; lastTime = currentTime; } } // Global controls document.getElementById('globalSpeed').addEventListener('input', (e) => { globalSpeed = parseFloat(e.target.value); document.getElementById('speedValue').textContent = globalSpeed + 'x'; // Update all active animations currentAnimations.forEach(animation => { if (animation.timeline) { animation.timeline.timeScale(globalSpeed); } }); }); document.getElementById('pauseAll').addEventListener('click', function() { isPaused = true; currentAnimations.forEach(animation => { if (animation.timeline) { animation.timeline.pause(); } }); this.classList.add('active'); document.getElementById('resumeAll').classList.remove('active'); }); document.getElementById('resumeAll').addEventListener('click', function() { isPaused = false; currentAnimations.forEach(animation => { if (animation.timeline) { animation.timeline.resume(); } }); this.classList.add('active'); document.getElementById('pauseAll').classList.remove('active'); }); document.getElementById('resetAll').addEventListener('click', function() { // Reset all effects currentAnimations.forEach(animation => { if (animation.timeline) { animation.timeline.restart(); animation.timeline.pause(); } }); // Reset elements to original state document.querySelectorAll('.text-effect-demo, .image-effect-demo').forEach(element => { element.style.transform = ''; element.style.filter = ''; element.style.animation = ''; }); activeEffects = 0; document.getElementById('activeEffects').textContent = activeEffects; }); // Text effects document.querySelectorAll('[data-effect]').forEach(card => { const effectType = card.dataset.effect; const demoElement = card.querySelector('.text-effect-demo, .image-effect-demo'); const playButton = card.querySelector('.play-effect'); playButton.addEventListener('click', () => { if (isPaused) return; const animationId = `${effectType}-${Date.now()}`; if (demoElement.classList.contains('text-effect-demo')) { // Text effect const animation = textEffects[effectType](demoElement, { duration: 2 / globalSpeed, ease: 'power2.out' }); if (animation && animation.timeline) { currentAnimations.set(animationId, animation); activeEffects++; document.getElementById('activeEffects').textContent = activeEffects; animation.timeline.eventCallback('onComplete', () => { currentAnimations.delete(animationId); activeEffects--; document.getElementById('activeEffects').textContent = activeEffects; }); } } else { // Image effect const animation = imageEffects[effectType](demoElement, { duration: 2 / globalSpeed, ease: 'power2.out' }); if (animation && animation.timeline) { currentAnimations.set(animationId, animation); activeEffects++; document.getElementById('activeEffects').textContent = activeEffects; animation.timeline.eventCallback('onComplete', () => { currentAnimations.delete(animationId); activeEffects--; document.getElementById('activeEffects').textContent = activeEffects; }); } } }); }); // Combined effects document.getElementById('playCombo').addEventListener('click', () => { if (isPaused) return; const textElement = document.getElementById('combo-text'); const imgElement = document.getElementById('combo-img'); const textAnim = textEffects.typewriter(textElement, { duration: 1.5 / globalSpeed }); const imgAnim = imageEffects.pulse(imgElement, { duration: 2 / globalSpeed }); if (textAnim && imgAnim) { activeEffects += 2; document.getElementById('activeEffects').textContent = activeEffects; textAnim.timeline.eventCallback('onComplete', () => activeEffects--); imgAnim.timeline.eventCallback('onComplete', () => activeEffects--); } }); document.getElementById('playSequence').addEventListener('click', () => { if (isPaused) return; const element = document.getElementById('sequence-demo'); const sequence = [ () => textEffects.fadeIn(element, { duration: 0.5 / globalSpeed }), () => textEffects.bounce(element, { duration: 1 / globalSpeed }), () => textEffects.wave(element, { duration: 1.5 / globalSpeed }), () => textEffects.fadeOut(element, { duration: 0.5 / globalSpeed }) ]; let currentIndex = 0; function playNext() { if (currentIndex < sequence.length) { const animation = sequence[currentIndex](); if (animation && animation.timeline) { activeEffects++; document.getElementById('activeEffects').textContent = activeEffects; animation.timeline.eventCallback('onComplete', () => { activeEffects--; document.getElementById('activeEffects').textContent = activeEffects; currentIndex++; playNext(); }); } } } playNext(); }); document.getElementById('playRandom').addEventListener('click', () => { if (isPaused) return; const element = document.getElementById('random-demo'); const effects = ['fadeIn', 'slideIn', 'bounce', 'wave', 'glitch']; const randomEffect = effects[Math.floor(Math.random() * effects.length)]; const animation = textEffects[randomEffect](element, { duration: 1.5 / globalSpeed, ease: 'power2.out' }); if (animation && animation.timeline) { activeEffects++; document.getElementById('activeEffects').textContent = activeEffects; animation.timeline.eventCallback('onComplete', () => { activeEffects--; document.getElementById('activeEffects').textContent = activeEffects; }); } }); // Performance loop function animate() { requestAnimationFrame(animate); updatePerformance(); } animate(); console.log('Advanced effects demo loaded successfully!'); console.log('Available text effects:', Object.getOwnPropertyNames(TextEffects.prototype)); console.log('Available image effects:', Object.getOwnPropertyNames(ImageEffects.prototype)); </script> </body> </html>