document.addEventListener('DOMContentLoaded', () => { // Initialize scene const container = document.getElementById('animation-container'); const lootBoxesContainer = document.getElementById('loot-boxes'); const rollButton = document.getElementById('roll-button'); // Box types and colors const boxTypes = [ { name: 'Common', class: 'common', chance: 60 }, { name: 'Rare', class: 'rare', chance: 25 }, { name: 'Epic', class: 'epic', chance: 10 }, { name: 'Legendary', class: 'legendary', chance: 5 } ]; // Generate loot boxes const totalBoxes = 12; const boxes = []; for (let i = 0; i < totalBoxes; i++) { const box = document.createElement('div'); box.className = 'loot-box'; // Determine box type based on chance const random = Math.random() * 100; let cumulativeChance = 0; let boxType; for (const type of boxTypes) { cumulativeChance += type.chance; if (random <= cumulativeChance) { boxType = type; break; } } box.innerHTML = `
${boxType.name}
`; boxes.push(box); lootBoxesContainer.appendChild(box); } // Add event listener to roll button rollButton.addEventListener('click', () => { if (lootBoxesContainer.classList.contains('rolling')) return; startRollAnimation(); startMultiplierRoll(); }); function startMultiplierRoll() { const multiplierSlider = document.getElementById('multiplier-slider'); multiplierSlider.classList.add('blurred'); const multipliers = Array.from(document.querySelectorAll('.multiplier-pill')); multipliers.forEach(pill => pill.classList.remove('selected')); // High-speed sliding phase const slideDistance = Math.random() * 3000 + 1500; gsap.to(multiplierSlider, { x: `-=${slideDistance}`, duration: 2.5, ease: 'power2.inOut', onComplete: () => { // Select a random multiplier (bias towards higher multipliers) const weightedMultipliers = [0,1,2,3,4,5,0,1,2,3,4,5]; const centerMultiplierIndex = Math.random() < 0.3 ? Math.floor(Math.random() * 3) + 6 : // Higher chance for better multipliers Math.floor(Math.random() * 6) + 3; // Normal distribution const selectedMultiplier = multipliers[weightedMultipliers[centerMultiplierIndex]]; selectedMultiplier.classList.add('selected'); // Align the selected multiplier to center const containerWidth = document.getElementById('multiplier-track').offsetWidth; const pillWidth = selectedMultiplier.offsetWidth; const pillOffset = selectedMultiplier.offsetLeft; const targetX = containerWidth / 2 - pillWidth / 2 - pillOffset; gsap.to(multiplierSlider, { x: targetX, duration: 0.8, ease: 'elastic.out(1, 0.5)', onComplete: () => { multiplierSlider.classList.remove('blurred'); } }); } }); } function startRollAnimation() { // Disable button during animation lootBoxesContainer.classList.add('rolling'); rollButton.classList.add('opacity-50', 'pointer-events-none'); // Clear previous selection document.querySelectorAll('.loot-box.selected').forEach(box => { box.classList.remove('selected'); }); // Add motion blur lootBoxesContainer.classList.add('motion-blur'); // Create speed lines const speedLines = document.createElement('div'); speedLines.className = 'speed-lines'; container.appendChild(speedLines); // Energy burst effect const energyBurst = document.createElement('div'); energyBurst.className = 'energy-burst'; energyBurst.style.width = '200px'; energyBurst.style.height = '200px'; energyBurst.style.left = rollButton.offsetLeft + rollButton.offsetWidth / 2 - 100 + 'px'; energyBurst.style.top = rollButton.offsetTop + rollButton.offsetHeight / 2 - 100 + 'px'; container.appendChild(energyBurst); // Animate energy burst gsap.to(energyBurst, { scale: 1.5, opacity: 0.8, duration: 0.3, ease: 'power2.out', onComplete: () => { gsap.to(energyBurst, { scale: 3, opacity: 0, duration: 0.5, onComplete: () => { energyBurst.remove(); } }); } }); // High-speed sliding phase const slideDistance = Math.random() * 5000 + 3000; gsap.to(lootBoxesContainer, { x: `-=${slideDistance}`, duration: 3, ease: 'power2.inOut', onUpdate: () => { // Add speed lines effect gsap.to(speedLines, { opacity: 0.5, duration: 0.1 }); }, onComplete: () => { // Remove speed lines gsap.to(speedLines, { opacity: 0, duration: 0.5, onComplete: () => { speedLines.remove(); } }); // Remove motion blur lootBoxesContainer.classList.remove('motion-blur'); // Select a random box (bias towards center boxes) const centerBoxIndex = Math.floor(Math.random() * 4) + 4; const selectedBox = boxes[centerBoxIndex]; selectedBox.classList.add('selected'); // Align the selected box to center const containerWidth = container.offsetWidth; const boxWidth = selectedBox.offsetWidth; const boxOffset = selectedBox.offsetLeft; const targetX = containerWidth / 2 - boxWidth / 2 - boxOffset; gsap.to(lootBoxesContainer, { x: targetX, duration: 0.8, ease: 'elastic.out(1, 0.5)', onComplete: () => { // Open the box after a delay setTimeout(() => { openBox(selectedBox); }, 500); } }); } }); } function openBox(box) { const lid = box.querySelector('.loot-box-lid'); const isLegendary = box.classList.contains('legendary'); // Animate lid opening gsap.to(lid, { rotationX: -120, transformOrigin: 'bottom', duration: 0.5, ease: 'back.out(1)' }); // Create light explosion const explosion = document.createElement('div'); explosion.className = 'absolute inset-0 rounded-full bg-amber-500/20 blur-xl'; explosion.style.width = '200px'; explosion.style.height = '200px'; explosion.style.left = '50%'; explosion.style.top = '50%'; explosion.style.transform = 'translate(-50%, -50%) scale(0)'; box.appendChild(explosion); // Animate explosion gsap.to(explosion, { scale: 2, opacity: 0.8, duration: 0.3, ease: 'power2.out', onComplete: () => { gsap.to(explosion, { scale: 3, opacity: 0, duration: 0.5, onComplete: () => { explosion.remove(); } }); } }); // Create particles createParticles(box, isLegendary); // Create prize reveal const prizeValue = isLegendary ? '5000 SC' : ['100 SC', '250 SC', '500 SC', '1000 SC'][Math.floor(Math.random() * 4)]; const prize = document.createElement('div'); prize.className = 'prize-reveal'; prize.textContent = prizeValue; box.appendChild(prize); // Enable button again setTimeout(() => { lootBoxesContainer.classList.remove('rolling'); rollButton.classList.remove('opacity-50', 'pointer-events-none'); }, 2000); } function createParticles(box, isLegendary) { const particleCount = isLegendary ? 30 : 15; const colors = isLegendary ? ['#FF8C00', '#FFD700', '#FFA500', '#FFFFFF'] : ['#FFFFFF', '#CCCCCC', '#AAAAAA']; for (let i = 0; i < particleCount; i++) { const particle = document.createElement('div'); particle.className = 'absolute rounded-full'; particle.style.width = Math.random() * 8 + 2 + 'px'; particle.style.height = particle.style.width; particle.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; particle.style.left = '50%'; particle.style.top = '50%'; particle.style.opacity = '0'; box.appendChild(particle); const angle = Math.random() * Math.PI * 2; const distance = Math.random() * 50 + 30; const duration = Math.random() * 1 + 0.5; gsap.to(particle, { x: Math.cos(angle) * distance, y: Math.sin(angle) * distance - 50, opacity: 1, duration: duration * 0.3, ease: 'power2.out' }); gsap.to(particle, { y: `-=${Math.random() * 30 + 20}`, opacity: 0, duration: duration * 0.7, delay: duration * 0.3, ease: 'power2.in', onComplete: () => { particle.remove(); } }); } } // Ambient animations setInterval(() => { const randomBox = boxes[Math.floor(Math.random() * boxes.length)]; if (!randomBox.classList.contains('selected') && !lootBoxesContainer.classList.contains('rolling')) { gsap.to(randomBox, { y: -10, duration: 1, yoyo: true, repeat: 1, ease: 'sine.inOut' }); } }, 3000); });