This commit is contained in:
Michal Vrba
2026-09-03 17:25:35 +02:00
parent 5d9194e14f
commit 00aa94ea7c
8 changed files with 323 additions and 18 deletions
+143 -5
View File
@@ -190,6 +190,26 @@ body, html {
transition: all 0.3s ease;
}
.player-slot.active-turn-slot::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 140%;
height: 140%;
background: radial-gradient(ellipse at center, rgba(245, 176, 65, 0.28) 0%, rgba(245, 176, 65, 0.08) 55%, transparent 75%);
pointer-events: none;
z-index: -1;
border-radius: 50%;
animation: aura-breathe 2.2s infinite ease-in-out alternate;
}
@keyframes aura-breathe {
0% { transform: translate(-50%, -50%) scale(0.92); opacity: 0.6; }
100% { transform: translate(-50%, -50%) scale(1.15); opacity: 1; }
}
.slot-top {
grid-row: 1;
grid-column: 2;
@@ -208,6 +228,22 @@ body, html {
.slot-bottom {
grid-row: 3;
grid-column: 1 / span 3;
position: relative;
}
.slot-bottom.active-turn-slot::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 320px;
height: 120px;
background: radial-gradient(ellipse at center, rgba(245, 176, 65, 0.22) 0%, rgba(245, 176, 65, 0.05) 50%, transparent 75%);
pointer-events: none;
z-index: -1;
border-radius: 50%;
animation: aura-breathe 2.2s infinite ease-in-out alternate;
}
.slot-center {
@@ -219,6 +255,35 @@ body, html {
gap: 20px;
}
/* TURN HEADER INFO */
.turn-header-info {
font-size: 0.95rem;
font-weight: 700;
color: #a3b899;
display: flex;
align-items: center;
gap: 6px;
}
.active-turn-header-player {
color: var(--gold);
font-weight: 900;
text-shadow: 0 0 10px rgba(245, 176, 65, 0.8);
background: rgba(245, 176, 65, 0.15);
padding: 2px 10px;
border-radius: 12px;
border: 1px solid rgba(245, 176, 65, 0.45);
display: inline-flex;
align-items: center;
gap: 4px;
animation: header-pulse 1.8s infinite alternate;
}
@keyframes header-pulse {
0% { box-shadow: 0 0 4px rgba(245, 176, 65, 0.3); }
100% { box-shadow: 0 0 16px rgba(245, 176, 65, 0.8); }
}
/* AVATAR BADGE */
.avatar-badge {
position: relative;
@@ -230,19 +295,92 @@ body, html {
border-radius: 16px;
padding: 6px 12px;
backdrop-filter: blur(8px);
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
transition: all 0.35s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.avatar-badge.active-turn {
border-color: var(--gold);
box-shadow: 0 0 20px rgba(245, 176, 65, 0.8), inset 0 0 10px rgba(245, 176, 65, 0.3);
transform: scale(1.08);
box-shadow: 0 0 25px rgba(245, 176, 65, 0.9), inset 0 0 12px rgba(245, 176, 65, 0.35);
transform: scale(1.09);
animation: turn-pulse 1.8s infinite;
}
@keyframes turn-pulse {
0%, 100% { box-shadow: 0 0 15px rgba(245, 176, 65, 0.7); }
50% { box-shadow: 0 0 25px rgba(245, 176, 65, 1), 0 0 40px rgba(245, 176, 65, 0.5); }
0%, 100% { box-shadow: 0 0 16px rgba(245, 176, 65, 0.7); }
50% { box-shadow: 0 0 30px rgba(245, 176, 65, 1), 0 0 45px rgba(245, 176, 65, 0.55); }
}
/* TURN INDICATOR BADGE (NA ŤAHU) */
.turn-indicator-badge {
position: absolute;
top: -14px;
left: 50%;
transform: translateX(-50%);
display: inline-flex;
align-items: center;
gap: 5px;
background: linear-gradient(135deg, #ffd700, #f5b041);
color: #11281d;
font-size: 0.66rem;
font-weight: 900;
letter-spacing: 0.8px;
padding: 2px 9px;
border-radius: 12px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.6), 0 0 14px rgba(255, 215, 0, 0.8);
border: 1.5px solid #ffffff;
white-space: nowrap;
z-index: 20;
animation: turn-badge-float 1.8s ease-in-out infinite alternate;
}
@keyframes turn-badge-float {
0% { transform: translateX(-50%) translateY(0); }
100% { transform: translateX(-50%) translateY(-3px); }
}
.turn-indicator-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background-color: #0d3824;
box-shadow: 0 0 4px #0d3824;
animation: dot-blink 1s ease-in-out infinite alternate;
}
@keyframes dot-blink {
0% { opacity: 0.4; transform: scale(0.75); }
100% { opacity: 1; transform: scale(1.25); }
}
/* TURN ARRIVAL EFFECT */
.turn-arrived-pulse {
animation: turn-arrival 0.55s cubic-bezier(0.175, 0.885, 0.32, 1.275) !important;
}
@keyframes turn-arrival {
0% { transform: scale(1); }
40% { transform: scale(1.18); box-shadow: 0 0 35px rgba(245, 176, 65, 1), 0 0 55px rgba(255, 215, 0, 0.8); }
100% { transform: scale(1.09); }
}
/* TURN TRANSFER ORB */
.turn-transfer-orb {
position: fixed;
width: 24px;
height: 24px;
border-radius: 50%;
background: radial-gradient(circle at 35% 35%, #ffffff, #ffd700 45%, #ff8c00 85%, transparent);
box-shadow: 0 0 18px rgba(255, 215, 0, 0.95), 0 0 36px rgba(245, 176, 65, 0.7);
transform: translate(-50%, -50%);
pointer-events: none;
z-index: 998;
filter: drop-shadow(0 0 10px rgba(245, 176, 65, 0.85));
animation: orb-glow 0.38s infinite alternate;
}
@keyframes orb-glow {
0% { transform: translate(-50%, -50%) scale(0.9); }
100% { transform: translate(-50%, -50%) scale(1.25); }
}
.avatar-icon {
+125
View File
@@ -461,6 +461,130 @@ window.FaraonFx = (function () {
}
}
// --- TURN TRANSITION ANIMATION ---
function getSlotElement(pos) {
if (!pos) return null;
const normalized = pos.replace('slot-', '');
if (normalized === 'bottom') {
return document.querySelector('.slot-bottom .avatar-badge') || document.querySelector('.slot-bottom');
}
return document.querySelector('.slot-' + normalized + ' .avatar-badge') || document.querySelector('.slot-' + normalized);
}
function playTurnPassSound() {
if (isMuted) return;
const ctx = getAudioContext();
if (!ctx) return;
const now = ctx.currentTime;
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.type = 'sine';
osc.frequency.setValueAtTime(540, now);
osc.frequency.exponentialRampToValueAtTime(820, now + 0.11);
gain.gain.setValueAtTime(0.07, now);
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.13);
osc.connect(gain);
gain.connect(ctx.destination);
osc.start(now);
osc.stop(now + 0.14);
}
function animateTurnTransition(fromPosition, toPosition) {
if (!fromPosition || !toPosition || fromPosition === toPosition) return Promise.resolve();
return new Promise((resolve) => {
const fromElem = getSlotElement(fromPosition);
const toElem = getSlotElement(toPosition);
const startPos = fromElem ? getElementCenter(fromElem) : getPositionCoords(fromPosition);
const endPos = toElem ? getElementCenter(toElem) : getPositionCoords(toPosition);
const container = document.getElementById('game-table-container') || document.body;
const orb = document.createElement('div');
orb.className = 'turn-transfer-orb';
orb.style.left = `${startPos.x}px`;
orb.style.top = `${startPos.y}px`;
container.appendChild(orb);
const midX = (startPos.x + endPos.x) / 2;
const midY = Math.min(startPos.y, endPos.y) - 35;
const duration = 380;
const startTime = performance.now();
function step(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const t = 1 - Math.pow(1 - progress, 3); // Ease out cubic
// Quadratic Bezier curve
const currentX = (1 - t) * (1 - t) * startPos.x + 2 * (1 - t) * t * midX + t * t * endPos.x;
const currentY = (1 - t) * (1 - t) * startPos.y + 2 * (1 - t) * t * midY + t * t * endPos.y;
orb.style.left = `${currentX}px`;
orb.style.top = `${currentY}px`;
if (particleCanvas && Math.random() < 0.4) {
particles.push({
x: currentX,
y: currentY,
vx: (Math.random() - 0.5) * 1.5,
vy: (Math.random() - 0.5) * 1.5,
gravity: 0,
size: 3 + Math.random() * 3,
color: Math.random() > 0.4 ? '#ffd700' : '#f5b041',
shape: 'spark',
life: 0.6,
decay: 0.04,
rotation: Math.random() * Math.PI
});
}
if (progress < 1) {
requestAnimationFrame(step);
} else {
orb.remove();
if (toElem) {
toElem.classList.remove('turn-arrived-pulse');
void toElem.offsetWidth;
toElem.classList.add('turn-arrived-pulse');
setTimeout(() => toElem.classList.remove('turn-arrived-pulse'), 600);
}
if (particleCanvas) {
for (let i = 0; i < 8; i++) {
const angle = Math.random() * Math.PI * 2;
const spd = 1.5 + Math.random() * 2.5;
particles.push({
x: endPos.x,
y: endPos.y,
vx: Math.cos(angle) * spd,
vy: Math.sin(angle) * spd,
gravity: 0.02,
size: 3 + Math.random() * 3,
color: '#ffd700',
shape: 'spark',
life: 0.7,
decay: 0.035,
rotation: Math.random() * Math.PI
});
}
}
playTurnPassSound();
resolve();
}
}
requestAnimationFrame(step);
});
}
// --- PARTICLE ENGINE ---
function initParticles(canvasId) {
particleCanvas = document.getElementById(canvasId);
@@ -912,6 +1036,7 @@ window.FaraonFx = (function () {
triggerGoldStarExplosion,
animateCardPlay,
animateCardDraw,
animateTurnTransition,
toggleMute
};
})();