// 平滑滚动效果 document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); // 数字动画效果 function animateValue(element, start, end, duration) { let startTimestamp = null; const step = (timestamp) => { if (!startTimestamp) startTimestamp = timestamp; const progress = Math.min((timestamp - startTimestamp) / duration, 1); const value = Math.floor(progress * (end - start) + start); element.textContent = value; if (progress < 1) { window.requestAnimationFrame(step); } }; window.requestAnimationFrame(step); } // 页面加载时触发数字动画 window.addEventListener('load', () => { const statNumbers = document.querySelectorAll('.stat-number'); statNumbers.forEach(stat => { const text = stat.textContent; if (text.includes('%')) { const value = parseInt(text); stat.textContent = '0%'; animateValue(stat, 0, value, 2000); setTimeout(() => { stat.textContent = value + '%'; }, 2000); } else if (text.includes('x')) { stat.textContent = '0x'; setTimeout(() => { stat.textContent = text; }, 1500); } else { const value = parseInt(text); animateValue(stat, 0, value, 2000); } }); }); // 滚动时的淡入效果 const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -100px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); } }); }, observerOptions); // 监听需要动画的元素 document.querySelectorAll('.chart-card, .pricing-card, .testimonial-card').forEach(el => { el.style.opacity = '0'; el.style.transform = 'translateY(30px)'; observer.observe(el); }); // 添加visible类的样式 const style = document.createElement('style'); style.textContent = ` .visible { opacity: 1 !important; transform: translateY(0) !important; transition: opacity 0.6s ease, transform 0.6s ease; } `; document.head.appendChild(style); // 导航栏滚动效果 let lastScroll = 0; const header = document.querySelector('header'); window.addEventListener('scroll', () => { const currentScroll = window.pageYOffset; if (currentScroll > 100) { header.style.boxShadow = '0 2px 10px rgba(0,0,0,0.1)'; } else { header.style.boxShadow = 'var(--shadow-sm)'; } lastScroll = currentScroll; }); // 按钮点击效果 document.querySelectorAll('.primary-button, .secondary-button, .pricing-button').forEach(button => { button.addEventListener('click', function(e) { // 创建涟漪效果 const ripple = document.createElement('span'); const rect = this.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = e.clientX - rect.left - size / 2; const y = e.clientY - rect.top - size / 2; ripple.style.width = ripple.style.height = size + 'px'; ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; ripple.classList.add('ripple'); this.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); }); }); // 添加涟漪效果样式 const rippleStyle = document.createElement('style'); rippleStyle.textContent = ` .primary-button, .secondary-button, .pricing-button { position: relative; overflow: hidden; } .ripple { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.5); transform: scale(0); animation: ripple-animation 0.6s ease-out; } @keyframes ripple-animation { to { transform: scale(4); opacity: 0; } } `; document.head.appendChild(rippleStyle); // 表格行悬停效果 document.querySelectorAll('tbody tr').forEach(row => { row.addEventListener('mouseenter', function() { this.style.transform = 'scale(1.02)'; this.style.transition = 'transform 0.3s ease'; }); row.addEventListener('mouseleave', function() { this.style.transform = 'scale(1)'; }); }); // 加载进度条动画 window.addEventListener('load', () => { const bars = document.querySelectorAll('.bar'); bars.forEach(bar => { const width = bar.style.width; bar.style.width = '0'; setTimeout(() => { bar.style.width = width; }, 500); }); }); // 演示画廊交互 const galleryItems = document.querySelectorAll('.gallery-item'); const prevBtn = document.querySelector('.demo-nav.prev'); const nextBtn = document.querySelector('.demo-nav.next'); let currentIndex = 0; function updateGallery(index) { galleryItems.forEach((item, i) => { item.classList.toggle('active', i === index); }); } if (prevBtn && nextBtn) { prevBtn.addEventListener('click', () => { currentIndex = (currentIndex - 1 + galleryItems.length) % galleryItems.length; updateGallery(currentIndex); }); nextBtn.addEventListener('click', () => { currentIndex = (currentIndex + 1) % galleryItems.length; updateGallery(currentIndex); }); } galleryItems.forEach((item, index) => { item.addEventListener('click', () => { currentIndex = index; updateGallery(currentIndex); }); });