mingle-website/js/main.js
2025-09-14 00:24:42 +09:00

128 lines
4.2 KiB
JavaScript

// ========================================
// 메인 페이지 전용 JavaScript
// ========================================
document.addEventListener('DOMContentLoaded', function() {
initMainPageAnimations();
initCounterAnimation();
});
// ========================================
// 메인 페이지 애니메이션
// ========================================
function initMainPageAnimations() {
// Hero 섹션 애니메이션
const heroElements = document.querySelectorAll('.hero-title, .hero-description, .hero-buttons');
heroElements.forEach((el, index) => {
el.style.opacity = '0';
el.style.transform = 'translateY(30px)';
setTimeout(() => {
el.style.transition = 'all 0.8s ease';
el.style.opacity = '1';
el.style.transform = 'translateY(0)';
}, 100 * (index + 1));
});
// Feature 카드 애니메이션
const observerOptions = {
threshold: 0.2,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry, index) => {
if (entry.isIntersecting) {
setTimeout(() => {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}, index * 100);
observer.unobserve(entry.target);
}
});
}, observerOptions);
// Feature 카드 초기 상태 설정 및 관찰
document.querySelectorAll('.feature-card').forEach(card => {
card.style.opacity = '0';
card.style.transform = 'translateY(30px)';
card.style.transition = 'all 0.6s ease';
observer.observe(card);
});
// Service 아이템 애니메이션
document.querySelectorAll('.service-item').forEach(item => {
item.style.opacity = '0';
item.style.transform = 'translateX(-30px)';
item.style.transition = 'all 0.6s ease';
observer.observe(item);
});
}
// ========================================
// 카운터 애니메이션 (선택적)
// ========================================
function initCounterAnimation() {
const counters = document.querySelectorAll('.counter');
if (counters.length === 0) return;
const animateCounter = (counter) => {
const target = parseInt(counter.getAttribute('data-target'));
const duration = 2000; // 2초
const increment = target / (duration / 16); // 60fps 기준
let current = 0;
const updateCounter = () => {
current += increment;
if (current < target) {
counter.textContent = Math.floor(current);
requestAnimationFrame(updateCounter);
} else {
counter.textContent = target;
}
};
updateCounter();
};
const counterObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animateCounter(entry.target);
counterObserver.unobserve(entry.target);
}
});
}, { threshold: 0.5 });
counters.forEach(counter => {
counterObserver.observe(counter);
});
}
// ========================================
// 패럴랙스 효과 (선택적)
// ========================================
window.addEventListener('scroll', () => {
const scrolled = window.pageYOffset;
const parallaxElements = document.querySelectorAll('.parallax');
parallaxElements.forEach(el => {
const speed = el.getAttribute('data-speed') || 0.5;
el.style.transform = `translateY(${scrolled * speed}px)`;
});
});
// ========================================
// 마우스 호버 효과
// ========================================
document.querySelectorAll('.feature-card, .service-item').forEach(card => {
card.addEventListener('mouseenter', function(e) {
const rect = this.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
this.style.setProperty('--mouse-x', `${x}px`);
this.style.setProperty('--mouse-y', `${y}px`);
});
});