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 = `
`;
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);
});