UNPKG

my-animation-lib

Version:

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

465 lines (390 loc) 15.8 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Three.js Demo - My Animation Library</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Arial', sans-serif; background: #000; color: white; overflow: hidden; } #threejs-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; } .ui-overlay { position: fixed; top: 20px; left: 20px; z-index: 1000; background: rgba(0, 0, 0, 0.8); padding: 1rem; border-radius: 10px; max-width: 300px; } .ui-overlay h3 { margin-bottom: 1rem; color: #00ff88; } .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: #333; 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; } .stats { position: fixed; top: 20px; right: 20px; z-index: 1000; background: rgba(0, 0, 0, 0.8); padding: 1rem; border-radius: 10px; font-family: monospace; font-size: 0.8rem; } .info-panel { position: fixed; bottom: 20px; left: 20px; z-index: 1000; background: rgba(0, 0, 0, 0.8); padding: 1rem; border-radius: 10px; max-width: 400px; } .info-panel h4 { color: #00ff88; margin-bottom: 0.5rem; } .info-panel p { font-size: 0.9rem; margin-bottom: 0.5rem; } .loading { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 2000; background: rgba(0, 0, 0, 0.9); padding: 2rem; border-radius: 10px; text-align: center; } .spinner { border: 4px solid #333; border-top: 4px solid #00ff88; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 0 auto 1rem; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style> </head> <body> <div id="threejs-container"></div> <div class="ui-overlay"> <h3>3D Controls</h3> <div class="control-group"> <label>Camera Position:</label> <input type="range" id="cameraX" min="-50" max="50" value="0" step="1"> <input type="range" id="cameraY" min="-50" max="50" value="0" step="1"> <input type="range" id="cameraZ" min="10" max="100" value="30" step="1"> </div> <div class="control-group"> <label>Rotation Speed:</label> <input type="range" id="rotationSpeed" min="0" max="0.1" value="0.01" step="0.001"> </div> <div class="control-group"> <label>Particle Count:</label> <input type="range" id="particleCount" min="100" max="5000" value="1000" step="100"> </div> <div class="control-group"> <button id="toggleRotation">Pause Rotation</button> <button id="toggleParticles">Toggle Particles</button> <button id="changeColor">Change Color</button> <button id="resetScene">Reset Scene</button> </div> <div class="control-group"> <label>Effect Type:</label> <select id="effectType"> <option value="basic">Basic Particles</option> <option value="fire">Fire Effect</option> <option value="smoke">Smoke Effect</option> <option value="sparkle">Sparkle Effect</option> <option value="rain">Rain Effect</option> <option value="snow">Snow Effect</option> </select> <button id="createEffect">Create Effect</button> </div> </div> <div class="stats"> <div>FPS: <span id="fps">0</span></div> <div>Objects: <span id="objectCount">0</span></div> <div>Particles: <span id="particleCount">0</span></div> <div>Memory: <span id="memory">0</span> MB</div> </div> <div class="info-panel"> <h4>Three.js Demo</h4> <p>Use the controls to manipulate the 3D scene:</p> <p>• Adjust camera position with sliders</p> <p>• Control rotation speed</p> <p>• Toggle particle systems</p> <p>• Create different particle effects</p> <p>• Use mouse to rotate camera view</p> </div> <div class="loading" id="loading"> <div class="spinner"></div> <p>Loading 3D Scene...</p> </div> <script type="module"> import { AnimationEngine, ThreeJSManager, ParticleEffects } from '../src/index.js'; // Initialize the animation engine const engine = new AnimationEngine(); await engine.init(); // Get Three.js manager const threeJSManager = engine.getThreeJSManager(); const container = document.getElementById('threejs-container'); // Initialize Three.js scene await threeJSManager.init(); container.appendChild(threeJSManager.renderer.domElement); // Initialize particle effects const particleEffects = new ParticleEffects(threeJSManager); // Create some basic 3D objects const cube = threeJSManager.createCube({ size: 5, color: 0x00ff88, position: { x: -10, y: 0, z: 0 } }); const sphere = threeJSManager.createSphere({ radius: 3, color: 0xff0088, position: { x: 10, y: 0, z: 0 } }); // Create initial particle system let currentParticleSystem = particleEffects.createParticleSystem({ count: 1000, size: 0.1, color: 0x00ffff, speed: 0.01, spread: 50 }); // Animation state let rotationEnabled = true; let particlesEnabled = true; let currentEffect = 'basic'; // Control event listeners document.getElementById('cameraX').addEventListener('input', (e) => { threeJSManager.camera.position.x = parseFloat(e.target.value); }); document.getElementById('cameraY').addEventListener('input', (e) => { threeJSManager.camera.position.y = parseFloat(e.target.value); }); document.getElementById('cameraZ').addEventListener('input', (e) => { threeJSManager.camera.position.z = parseFloat(e.target.value); }); document.getElementById('rotationSpeed').addEventListener('input', (e) => { threeJSManager.rotationSpeed = parseFloat(e.target.value); }); document.getElementById('particleCount').addEventListener('input', (e) => { const count = parseInt(e.target.value); document.getElementById('particleCount').textContent = count; }); document.getElementById('toggleRotation').addEventListener('click', function() { rotationEnabled = !rotationEnabled; this.textContent = rotationEnabled ? 'Pause Rotation' : 'Resume Rotation'; this.classList.toggle('active'); }); document.getElementById('toggleParticles').addEventListener('click', function() { particlesEnabled = !particlesEnabled; this.textContent = particlesEnabled ? 'Hide Particles' : 'Show Particles'; this.classList.toggle('active'); const system = particleEffects.getParticleSystem(currentParticleSystem); if (system) { system.particles.visible = particlesEnabled; } }); document.getElementById('changeColor').addEventListener('click', function() { const colors = [0x00ff88, 0xff0088, 0x0088ff, 0xffff00, 0xff8800, 0x8800ff]; const randomColor = colors[Math.floor(Math.random() * colors.length)]; // Change cube color if (cube && cube.material) { cube.material.color.setHex(randomColor); } // Change sphere color if (sphere && sphere.material) { sphere.material.color.setHex(colors[(colors.indexOf(randomColor) + 1) % colors.length]); } }); document.getElementById('resetScene').addEventListener('click', function() { // Reset camera position threeJSManager.camera.position.set(0, 0, 30); threeJSManager.camera.lookAt(0, 0, 0); // Reset sliders document.getElementById('cameraX').value = 0; document.getElementById('cameraY').value = 0; document.getElementById('cameraZ').value = 30; // Reset rotation speed threeJSManager.rotationSpeed = 0.01; document.getElementById('rotationSpeed').value = 0.01; // Reset objects if (cube) cube.rotation.set(0, 0, 0); if (sphere) sphere.rotation.set(0, 0, 0); }); document.getElementById('createEffect').addEventListener('click', function() { const effectType = document.getElementById('effectType').value; // Remove current particle system if (currentParticleSystem) { particleEffects.removeParticleSystem(currentParticleSystem); } // Create new effect based on selection switch (effectType) { case 'fire': currentParticleSystem = particleEffects.createFireEffect({ position: { x: 0, y: -10, z: 0 }, intensity: 1.5 }); break; case 'smoke': currentParticleSystem = particleEffects.createSmokeEffect({ position: { x: 0, y: -10, z: 0 }, intensity: 1 }); break; case 'sparkle': currentParticleSystem = particleEffects.createSparkleEffect({ position: { x: 0, y: 0, z: 0 }, count: 300 }); break; case 'rain': currentParticleSystem = particleEffects.createRainEffect({ intensity: 1.5 }); break; case 'snow': currentParticleSystem = particleEffects.createSnowEffect({ intensity: 1 }); break; default: currentParticleSystem = particleEffects.createParticleSystem({ count: parseInt(document.getElementById('particleCount').value), size: 0.1, color: 0x00ffff, speed: 0.01, spread: 50 }); } currentEffect = effectType; }); // Mouse controls for camera rotation let mouseDown = false; let mouseX = 0; let mouseY = 0; container.addEventListener('mousedown', (e) => { mouseDown = true; mouseX = e.clientX; mouseY = e.clientY; }); container.addEventListener('mouseup', () => { mouseDown = false; }); container.addEventListener('mousemove', (e) => { if (mouseDown) { const deltaX = e.clientX - mouseX; const deltaY = e.clientY - mouseY; threeJSManager.camera.position.x += deltaX * 0.01; threeJSManager.camera.position.y -= deltaY * 0.01; mouseX = e.clientX; mouseY = e.clientY; } }); // Performance monitoring let frameCount = 0; let lastTime = performance.now(); let fps = 0; function updateStats() { frameCount++; const currentTime = performance.now(); if (currentTime - lastTime >= 1000) { fps = Math.round((frameCount * 1000) / (currentTime - lastTime)); document.getElementById('fps').textContent = fps; const objectCount = threeJSManager.scene.children.length; document.getElementById('objectCount').textContent = objectCount; const particleCount = particleEffects.getParticleSystemCount(); document.getElementById('particleCount').textContent = particleCount; // Memory usage (approximate) if (performance.memory) { const memoryMB = Math.round(performance.memory.usedJSHeapSize / 1024 / 1024); document.getElementById('memory').textContent = memoryMB; } frameCount = 0; lastTime = currentTime; } } // Custom animation loop function animate() { requestAnimationFrame(animate); const deltaTime = 0.016; // Approximate 60fps // Update particle effects if (particlesEnabled) { particleEffects.update(deltaTime); } // Update Three.js manager threeJSManager.animate(); // Update stats updateStats(); } // Start animation animate(); // Hide loading screen document.getElementById('loading').style.display = 'none'; console.log('Three.js demo loaded successfully!'); console.log('Created scene with', threeJSManager.scene.children.length, 'objects'); console.log('Particle system ID:', currentParticleSystem); </script> </body> </html>