// ======================================== // 메인 페이지 전용 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`); }); });