Files
7xl-home/script.js
T
2026-09-02 15:38:38 +00:00

267 lines
6.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 7XL – Interactive Features
* Clean, accessible, respects user preferences
*/
(function() {
'use strict';
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
/**
* Header scroll behavior
*/
function initHeader() {
const header = document.querySelector('.site-header');
if (!header) return;
let ticking = false;
function handleScroll() {
if (!ticking) {
requestAnimationFrame(() => {
if (window.pageYOffset > 40) {
header.classList.add('scrolled');
} else {
header.classList.remove('scrolled');
}
ticking = false;
});
ticking = true;
}
}
window.addEventListener('scroll', handleScroll, { passive: true });
handleScroll();
}
/**
* Mobile menu toggle
*/
function initMobileMenu() {
const toggle = document.querySelector('.mobile-toggle');
const mobileNav = document.querySelector('.mobile-nav');
if (!toggle || !mobileNav) return;
toggle.addEventListener('click', () => {
const isExpanded = toggle.getAttribute('aria-expanded') === 'true';
toggle.setAttribute('aria-expanded', !isExpanded);
mobileNav.hidden = isExpanded;
if (!isExpanded) {
const firstLink = mobileNav.querySelector('a');
if (firstLink) firstLink.focus();
}
});
// Close on link click
mobileNav.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
toggle.setAttribute('aria-expanded', 'false');
mobileNav.hidden = true;
});
});
// Close on escape
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && !mobileNav.hidden) {
toggle.setAttribute('aria-expanded', 'false');
mobileNav.hidden = true;
toggle.focus();
}
});
}
/**
* Scroll reveal animations
*/
function initScrollReveal() {
if (prefersReducedMotion) return;
const revealElements = document.querySelectorAll(
'.feature-card, .sport-card, .casino-game, .bonus-card, .bonus-main, .section-header'
);
if (!revealElements.length) return;
revealElements.forEach(el => el.classList.add('reveal'));
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
observer.unobserve(entry.target);
}
});
},
{
threshold: 0.15,
rootMargin: '0px 0px -40px 0px'
}
);
revealElements.forEach(el => observer.observe(el));
}
/**
* Smooth scroll for anchor links
*/
function initSmoothScroll() {
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
const targetId = this.getAttribute('href');
if (targetId === '#') return;
const target = document.querySelector(targetId);
if (target) {
e.preventDefault();
const header = document.querySelector('.site-header');
const offset = header ? header.offsetHeight + 16 : 80;
const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - offset;
window.scrollTo({
top: targetPosition,
behavior: prefersReducedMotion ? 'auto' : 'smooth'
});
// Set focus for accessibility
target.setAttribute('tabindex', '-1');
target.focus({ preventScroll: true });
}
});
});
}
/**
* Pause animations when not in view (performance)
*/
function initAnimationPausing() {
if (prefersReducedMotion) return;
const roulette = document.querySelector('.roulette-wheel');
if (!roulette) return;
// Add animation via JS so it only runs when visible
const style = document.createElement('style');
style.textContent = `
.roulette-wheel.animate {
animation: spin 15s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
`;
document.head.appendChild(style);
const observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
roulette.classList.add('animate');
} else {
roulette.classList.remove('animate');
}
});
},
{ threshold: 0.3 }
);
observer.observe(roulette);
}
/**
* Floating cards animation (CSS-only when visible)
*/
function initFloatingCards() {
if (prefersReducedMotion) return;
const style = document.createElement('style');
style.textContent = `
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-12px); }
}
.floating-card.animate {
animation: float 5s ease-in-out infinite;
}
.floating-card.card-2.animate {
animation-delay: 1.5s;
}
.floating-card.card-3.animate {
animation-delay: 3s;
}
`;
document.head.appendChild(style);
const cards = document.querySelectorAll('.floating-card');
if (!cards.length) return;
const observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
cards.forEach(card => {
if (entry.isIntersecting) {
card.classList.add('animate');
} else {
card.classList.remove('animate');
}
});
});
},
{ threshold: 0.2 }
);
const heroVisual = document.querySelector('.hero-visual');
if (heroVisual) observer.observe(heroVisual);
}
/**
* Live pulse animation
*/
function initLivePulse() {
if (prefersReducedMotion) return;
const style = document.createElement('style');
style.textContent = `
@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.4); opacity: 0.6; }
}
.live-pulse {
animation: pulse 1.5s ease-in-out infinite;
}
.live-indicator {
animation: blink 1.2s ease-in-out infinite;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
`;
document.head.appendChild(style);
}
/**
* Initialize all features
*/
function init() {
initHeader();
initMobileMenu();
initScrollReveal();
initSmoothScroll();
initAnimationPausing();
initFloatingCards();
initLivePulse();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();