// Modern Project Detail Page Enhancements document.addEventListener('DOMContentLoaded', function() { // Animate counter numbers function animateCounters() { const counters = document.querySelectorAll('.stat-number[data-target]'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const counter = entry.target; const target = parseInt(counter.dataset.target); const duration = 2000; // 2 seconds const step = target / (duration / 16); // 60fps let current = 0; const timer = setInterval(() => { current += step; counter.textContent = Math.floor(current); if (current >= target) { counter.textContent = target; clearInterval(timer); } }, 16); observer.unobserve(counter); } }); }, { threshold: 0.5 }); counters.forEach(counter => observer.observe(counter)); } // Scroll-triggered animations function initScrollAnimations() { const animatedElements = document.querySelectorAll('.content-section, .tech-item, .info-item'); 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); } }); }, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }); animatedElements.forEach(el => { el.style.opacity = '0'; el.style.transform = 'translateY(30px)'; el.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; observer.observe(el); }); } // Share functionality function initShareButton() { const shareBtn = document.querySelector('.share-btn'); if (shareBtn) { shareBtn.addEventListener('click', async function() { const projectTitle = document.querySelector('.hero-title').textContent; const url = window.location.href; if (navigator.share) { try { await navigator.share({ title: projectTitle, text: `Посмотрите на этот проект: ${projectTitle}`, url: url }); } catch (err) { console.log('Sharing failed:', err); fallbackShare(url); } } else { fallbackShare(url); } }); } } function fallbackShare(url) { // Copy to clipboard as fallback if (navigator.clipboard) { navigator.clipboard.writeText(url).then(() => { showToast('Ссылка скопирована в буфер обмена!'); }); } } function showToast(message) { // Create toast notification const toast = document.createElement('div'); toast.className = 'toast-notification'; toast.textContent = message; toast.style.cssText = ` position: fixed; top: 20px; right: 20px; background: linear-gradient(135deg, #48bb78, #38a169); color: white; padding: 1rem 1.5rem; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); z-index: 10000; transform: translateX(400px); transition: transform 0.3s ease; `; document.body.appendChild(toast); setTimeout(() => { toast.style.transform = 'translateX(0)'; }, 100); setTimeout(() => { toast.style.transform = 'translateX(400px)'; setTimeout(() => document.body.removeChild(toast), 300); }, 3000); } // Tech item hover effects function initTechInteractions() { const techItems = document.querySelectorAll('.tech-item'); techItems.forEach(item => { item.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-8px) scale(1.02)'; }); item.addEventListener('mouseleave', function() { this.style.transform = 'translateY(-5px) scale(1)'; }); }); } // Parallax effect for hero background function initParallaxEffect() { const heroBackground = document.querySelector('.hero-pattern'); if (!heroBackground) return; let ticking = false; function updateParallax() { const scrolled = window.pageYOffset; const rate = scrolled * -0.3; heroBackground.style.transform = `translateY(${rate}px)`; ticking = false; } function requestTick() { if (!ticking) { requestAnimationFrame(updateParallax); ticking = true; } } window.addEventListener('scroll', requestTick); } // Smooth scroll for internal links function initSmoothScroll() { const links = document.querySelectorAll('a[href^="#"]'); links.forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); const targetId = this.getAttribute('href'); const targetSection = document.querySelector(targetId); if (targetSection) { targetSection.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); } // Initialize all enhancements animateCounters(); initScrollAnimations(); initShareButton(); initTechInteractions(); initParallaxEffect(); initSmoothScroll(); // Add loading class removal after page load window.addEventListener('load', function() { document.body.classList.add('page-loaded'); }); }); // CSS for page loading animation const loadingStyles = ` body:not(.page-loaded) .project-hero { opacity: 0; transform: translateY(50px); transition: opacity 0.8s ease, transform 0.8s ease; } body.page-loaded .project-hero { opacity: 1; transform: translateY(0); } .toast-notification { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 0.9rem; font-weight: 500; } `; // Inject loading styles const styleSheet = document.createElement('style'); styleSheet.textContent = loadingStyles; document.head.appendChild(styleSheet);