2024-12-30 14:36:23 +08:00

217 lines
6.4 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function() {
AOS.init({
duration: 1000,
once: true,
offset: 100,
disable: '.parallax-section' // Disable AOS for parallax section
});
const swiper = new Swiper('.hero-slider', {
loop: true,
speed: 1000,
autoplay: {
delay: 5000,
disableOnInteraction: false,
},
pagination: {
el: '.swiper-pagination',
clickable: true,
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
});
const magneticLinks = document.querySelectorAll('.magnetic-link');
magneticLinks.forEach(link => {
link.addEventListener('mousemove', function(e) {
const bounds = this.getBoundingClientRect();
const mouseX = e.clientX - bounds.left;
const mouseY = e.clientY - bounds.top;
const centerX = bounds.width / 2;
const centerY = bounds.height / 2;
const deltaX = mouseX - centerX;
const deltaY = mouseY - centerY;
gsap.to(this, {
x: deltaX * 0.3,
y: deltaY * 0.3,
duration: 0.3
});
});
link.addEventListener('mouseleave', function() {
gsap.to(this, {
x: 0,
y: 0,
duration: 0.3
});
});
});
gsap.registerPlugin(ScrollTrigger);
const timelineItems = document.querySelectorAll('.timeline-item');
timelineItems.forEach((item, index) => {
const tl = gsap.timeline({
scrollTrigger: {
trigger: item,
start: "top center+=100",
end: "bottom center",
toggleActions: "play none none reverse"
}
});
tl.from(item.querySelector('::before'), {
scale: 0,
opacity: 0,
duration: 0.6,
ease: "back.out(1.7)"
});
tl.from(item.querySelector('.timeline-content'), {
x: index % 2 === 0 ? 50 : -50,
opacity: 0,
duration: 0.8,
ease: "power2.out"
}, "-=0.3");
tl.from(item.querySelector('.timeline-period'), {
y: 20,
opacity: 0,
duration: 0.5,
ease: "power2.out"
}, "-=0.4");
});
VanillaTilt.init(document.querySelectorAll('.digital-card'), {
max: 15,
speed: 400,
glare: true,
'max-glare': 0.2
});
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
window.scrollTo({
top: target.offsetTop - 70,
behavior: 'smooth'
});
}
});
});
const patternOverlay = document.querySelector('.pattern-overlay');
window.addEventListener('mousemove', (e) => {
const moveX = (e.clientX - window.innerWidth / 2) * 0.01;
const moveY = (e.clientY - window.innerHeight / 2) * 0.01;
gsap.to(patternOverlay, {
x: moveX,
y: moveY,
duration: 1,
ease: 'power2.out'
});
});
const exhibitionCards = document.querySelectorAll('.exhibition-card');
exhibitionCards.forEach(card => {
card.addEventListener('mouseenter', () => {
gsap.to(card, {
y: -10,
scale: 1.02,
duration: 0.3,
ease: 'power2.out'
});
});
card.addEventListener('mouseleave', () => {
gsap.to(card, {
y: 0,
scale: 1,
duration: 0.3,
ease: 'power2.out'
});
});
});
function createParticles() {
const particleContainer = document.createElement('div');
particleContainer.className = 'particle-container';
document.body.appendChild(particleContainer);
for (let i = 0; i < 50; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
particle.style.left = Math.random() * 100 + 'vw';
particle.style.animationDelay = Math.random() * 5 + 's';
particleContainer.appendChild(particle);
}
}
document.addEventListener('DOMContentLoaded', () => {
createParticles();
const scrollElements = document.querySelectorAll('.bamboo-content > *');
scrollElements.forEach(element => {
element.style.opacity = '0';
element.style.transform = 'translateX(-20px)';
});
const revealOnScroll = () => {
scrollElements.forEach(element => {
const elementTop = element.getBoundingClientRect().top;
if (elementTop < window.innerHeight - 100) {
element.style.opacity = '1';
element.style.transform = 'translateX(0)';
element.style.transition = 'all 0.8s ease';
}
});
};
window.addEventListener('scroll', revealOnScroll);
revealOnScroll();
});
function animateCounter(element) {
const target = parseInt(element.dataset.target);
const duration = 2000;
const step = target / (duration / 16); // 60fps
let current = 0;
const updateCounter = () => {
current += step;
if (current < target) {
element.textContent = Math.floor(current);
requestAnimationFrame(updateCounter);
} else {
element.textContent = target;
}
};
updateCounter();
}
const observerOptions = {
threshold: 0.5
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const counters = entry.target.querySelectorAll('.counter');
counters.forEach(counter => animateCounter(counter));
observer.unobserve(entry.target);
}
});
}, observerOptions);
document.querySelectorAll('.stats-section').forEach(section => {
observer.observe(section);
});
});