diff --git a/app/components/home/HomePartnersWork.vue b/app/components/home/HomePartnersWork.vue index ab89478..ed9d80b 100755 --- a/app/components/home/HomePartnersWork.vue +++ b/app/components/home/HomePartnersWork.vue @@ -100,66 +100,83 @@ onMounted(async () => { await nextTick() - ctx = gsap.context(() => { - const cards = cardRefs.value - const count = cards.length + // 延迟初始化 ScrollTrigger,避免阻塞首屏 Hero 动画 + // 等待 Hero 入场动画完成(约 3-4 秒) + const initScrollAnimation = () => { + ctx = gsap.context(() => { + const cards = cardRefs.value + const count = cards.length - if (count < 2) return + if (count < 2) return - const enterOffset = 160 - const scaleTo = 0.92 - const depthOffsetY = -18 + const enterOffset = 160 + const scaleTo = 0.92 + const depthOffsetY = -18 - for (let i = 0; i < count; i += 1) { - const card = cards[i] + for (let i = 0; i < count; i += 1) { + const card = cards[i] - gsap.set(card, { - position: 'absolute', - inset: 0, - borderRadius: 22, - overflow: 'hidden', - transformOrigin: 'center center', - force3D: true, - zIndex: i + 1, - boxShadow: '0 18px 40px rgba(0,0,0,0.12)', - y: i === 0 ? 0 : window.innerHeight + enterOffset, - scale: 1, + gsap.set(card, { + position: 'absolute', + inset: 0, + borderRadius: 22, + overflow: 'hidden', + transformOrigin: 'center center', + force3D: true, + zIndex: i + 1, + boxShadow: '0 18px 40px rgba(0,0,0,0.12)', + y: i === 0 ? 0 : window.innerHeight + enterOffset, + scale: 1, + }) + } + + const tl = gsap.timeline() + + for (let i = 1; i < count; i += 1) { + const prev = cards[i - 1] + const next = cards[i] + const start = i - 1 + + tl.to( + next, + { y: 0, duration: 1, ease: 'power2.out' }, + start + ) + tl.to( + prev, + { scale: scaleTo, y: depthOffsetY, duration: 0.6, ease: 'power2.out' }, + start + 0.35 + ) + tl.set(prev, { scale: scaleTo, y: depthOffsetY }, start + 1) + } + + ScrollTrigger.create({ + trigger: workSectionRef.value, + start: 'top top', + end: () => `+=${(count - 1) * window.innerHeight}`, + pin: workPinRef.value, + scrub: true, + anticipatePin: 1, + invalidateOnRefresh: true, + animation: tl, }) - } - const tl = gsap.timeline() + ScrollTrigger.refresh() + }, rootRef.value) + } - for (let i = 1; i < count; i += 1) { - const prev = cards[i - 1] - const next = cards[i] - const start = i - 1 + // 监听 hero 动画完成事件 + if (typeof window !== 'undefined') { + window.addEventListener('hero-intro-done', initScrollAnimation, { once: true }) - tl.to( - next, - { y: 0, duration: 1, ease: 'power2.out' }, - start - ) - tl.to( - prev, - { scale: scaleTo, y: depthOffsetY, duration: 0.6, ease: 'power2.out' }, - start + 0.35 - ) - tl.set(prev, { scale: scaleTo, y: depthOffsetY }, start + 1) - } - - ScrollTrigger.create({ - trigger: workSectionRef.value, - start: 'top top', - end: () => `+=${(count - 1) * window.innerHeight}`, - pin: workPinRef.value, - scrub: true, - anticipatePin: 1, - invalidateOnRefresh: true, - animation: tl, - }) - - ScrollTrigger.refresh() - }, rootRef.value) + // 保底:3秒后必定初始化 + setTimeout(() => { + window.removeEventListener('hero-intro-done', initScrollAnimation) + if (!ctx) { + initScrollAnimation() + } + }, 3000) + } }) onUnmounted(() => {