/** * 首页动效编排 * - Lenis 平滑滚动 * - GSAP ScrollTrigger 驱动的分区揭示、扫描线签名效果 * - 首屏加载时的标题错落浮现 * - 产品卡片的 3D 悬浮跟随 */ (function () { var prefersReducedMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; /* ---------- 1. Lenis 平滑滚动 ---------- */ var lenis = null; if (window.Lenis && !prefersReducedMotion) { lenis = new Lenis({ duration: 1.15, easing: function (t) { return Math.min(1, 1.001 - Math.pow(2, -10 * t)); }, smoothWheel: true, wheelMultiplier: 1 }); if (window.gsap && window.ScrollTrigger) { lenis.on('scroll', ScrollTrigger.update); gsap.ticker.add(function (time) { lenis.raf(time * 1000); }); gsap.ticker.lagSmoothing(0); } else { requestAnimationFrame(function raf(time) { lenis.raf(time); requestAnimationFrame(raf); }); } } /* ---------- 2. 首屏标题错落浮现 ---------- */ var revealItems = document.querySelectorAll('[data-reveal-item]'); if (window.gsap && revealItems.length) { gsap.set(revealItems, { opacity: 0, y: 26 }); gsap.to(revealItems, { opacity: 1, y: 0, duration: 0.9, ease: 'power3.out', stagger: 0.16, delay: 0.3 }); } if (!window.gsap || !window.ScrollTrigger) { return; // 没有 GSAP 时,直接跳过滚动动效,保留静态可读的页面 } gsap.registerPlugin(ScrollTrigger); /* ---------- 3. 分区揭示 + 扫描线签名效果 ---------- */ document.querySelectorAll('.reveal-section').forEach(function (section) { var revealTargets = section.querySelectorAll('.reveal-up'); var scanLine = section.querySelector('.section-scan'); if (revealTargets.length) { gsap.set(revealTargets, { opacity: 0, y: 40 }); gsap.to(revealTargets, { opacity: 1, y: 0, duration: 0.9, ease: 'power3.out', stagger: 0.14, scrollTrigger: { trigger: section, start: 'top 78%', once: true } }); } }); /* ---------- 4. 产品卡片 3D 悬浮跟随 ---------- */ document.querySelectorAll('.tilt-card').forEach(function (card) { var bounds; card.addEventListener('mouseenter', function () { bounds = card.getBoundingClientRect(); card.classList.add('is-tilting'); }); card.addEventListener('mousemove', function (e) { if (!bounds) bounds = card.getBoundingClientRect(); var px = (e.clientX - bounds.left) / bounds.width - 0.5; var py = (e.clientY - bounds.top) / bounds.height - 0.5; gsap.to(card, { rotateX: py * -8, rotateY: px * 10, duration: 0.4, ease: 'power2.out', transformPerspective: 700 }); }); card.addEventListener('mouseleave', function () { card.classList.remove('is-tilting'); gsap.to(card, { rotateX: 0, rotateY: 0, duration: 0.6, ease: 'power3.out' }); }); }); /* ---------- 5. Hero logo 视差微动 ---------- */ var heroLogo = document.querySelector('.hero-brand-logo'); var hero = document.querySelector('.hero'); if (heroLogo && hero && !prefersReducedMotion) { hero.addEventListener('mousemove', function (e) { var rect = hero.getBoundingClientRect(); var px = (e.clientX - rect.left) / rect.width - 0.5; var py = (e.clientY - rect.top) / rect.height - 0.5; gsap.to(heroLogo, { x: px * 14, y: py * 10, duration: 0.6, ease: 'power2.out' }); }); } })();