';
}
function animateValue(el, from, to, duration, prefix){
const start = performance.now();
function frame(now){
const progress = Math.min((now - start) / duration, 1);
const eased = 1 - Math.pow(1 - progress, 3);
const value = Math.round(from + (to - from) * eased);
el.textContent = (prefix || '₱') + value.toLocaleString();
if(progress < 1){
requestAnimationFrame(frame);
}
}
requestAnimationFrame(frame);
}
function calculateWin(result){
const keys = result.map(function(item){
return item.key;
});
const same3 = keys[0] === keys[1] && keys[1] === keys[2];
const same2 = keys[0] === keys[1] || keys[1] === keys[2] || keys[0] === keys[2];
if(same3 && keys[0] === 'seven') return bet * 12;
if(same3 && keys[0] === 'crown') return bet * 10;
if(same3 && keys[0] === 'diamond') return bet * 8;
if(same3 && keys[0] === 'star') return bet * 7;
if(same3) return bet * 6;
if(same2) return bet * 2;
return 0;
}
function openModal(title, text, amount){
modalTitle.textContent = title;
modalText.textContent = text;
modal.classList.add('show');
modalWinWrap.style.display = 'block';
if(amount > 0){
modalWinWrap.classList.add('active');
animateValue(modalWin, 0, amount, 1050, '₱');
}else{
modalWin.textContent = '₱0';
modalWinWrap.classList.remove('active');
}
}
function closeModal(){
modal.classList.remove('show');
modalWinWrap.classList.remove('active');
}
function popBonusEffects(){
winEl.classList.remove('win-pop');
lastWinEl.classList.remove('win-flash');
void winEl.offsetWidth;
void lastWinEl.offsetWidth;
winEl.classList.add('win-pop');
lastWinEl.classList.add('win-flash');
setTimeout(function(){
winEl.classList.remove('win-pop');
lastWinEl.classList.remove('win-flash');
}, 1500);
}
function spin(){
if(spinning) return;
if(balance < bet){
openModal('Saldo baixo', 'Seu saldo está muito baixo. Escolha uma aposta menor ou toque em CADASTRE-SE AGORA para continuar.', 0);
return;
}
closeModal();
spinning = true;
spinBtn.disabled = true;
balance -= bet;
jackpot += Math.floor(Math.random() * 450) + 80;
lastWin = 0;
updateUI();
setStatus('Girando... Boa sorte!');
reels.forEach(function(reel){
reel.classList.add('spinning');
});
let ticks = 0;
const rolling = setInterval(function(){
reels.forEach(function(reel){
renderSymbol(reel, pickSymbol());
});
ticks++;
if(ticks >= 18){
clearInterval(rolling);
const result = [pickSymbol(), pickSymbol(), pickSymbol()];
result.forEach(function(symbol, index){
setTimeout(function(){
renderSymbol(reels[index], symbol);
reels[index].classList.remove('spinning');
}, index * 280);
});
setTimeout(function(){
const bonus = calculateWin(result);
lastWin = bonus;
totalWin += bonus;
balance += bonus;
updateUI();
if(bonus > 0){
popBonusEffects();
setStatus('Parabéns! Você recebeu ' + money(bonus) + ' de bônus.');
setTimeout(function(){
openModal('PARABÉNS!', 'Você ganhou um prêmio! Continue girando ou entre no lobby do jogo para receber prêmios maiores.', bonus);
}, 1100);
}else{
setStatus('Esta rodada não teve prêmio. Tente novamente!');
setTimeout(function(){
openModal('TENTE NOVAMENTE', 'Esta rodada não foi sortuda. Gire mais uma vez!', 0);
}, 1250);
}
spinning = false;
spinBtn.disabled = false;
}, 1300);
}
}, 95);
}
chipBtns.forEach(function(btn){
btn.addEventListener('click', function(){
if(spinning) return;
bet = parseInt(btn.dataset.bet, 10);
chipBtns.forEach(function(item){
item.classList.remove('active');
});
btn.classList.add('active');
updateUI();
setStatus('Aposta selecionada de ' + money(bet) + '. Pressione GIRAR AGORA.');
});
});
spinBtn.addEventListener('click', spin);
againBtn.addEventListener('click', function(){
closeModal();
setTimeout(spin, 220);
});
modal.addEventListener('click', function(e){
if(e.target === modal){
closeModal();
}
});
updateUI();
})();