feat(HomeHero): 添加小字文本向上浮现动画效果
为服务列表、描述文本、按钮和小圆点等元素添加统一的向上浮现动画效果 使用GSAP实现动画序列,与大标题动画协调
This commit is contained in:
@@ -33,10 +33,16 @@ const play = () => new Promise<void>((resolve) => {
|
|||||||
const studioChars = gsap.utils.toArray('.hero-studio-char', studioNameRef.value)
|
const studioChars = gsap.utils.toArray('.hero-studio-char', studioNameRef.value)
|
||||||
const tm = brandNameRef.value?.querySelector('.hero-brand-tm')
|
const tm = brandNameRef.value?.querySelector('.hero-brand-tm')
|
||||||
|
|
||||||
// 初始隐藏底部文字:通过 autoAlpha (opacity + visibility) 控制,不仅下移而且完全不可见
|
// 获取所有需要统一从下浮现的其他文本节点(服务列表、描述、版权等)
|
||||||
|
const fadeUpItems = gsap.utils.toArray('.hero-fade-up', heroPanelRef.value)
|
||||||
|
|
||||||
|
// 初始隐藏底部大字文字
|
||||||
gsap.set([...brandChars, ...studioChars], { yPercent: 110, autoAlpha: 0 })
|
gsap.set([...brandChars, ...studioChars], { yPercent: 110, autoAlpha: 0 })
|
||||||
if (tm) gsap.set(tm, { autoAlpha: 0 })
|
if (tm) gsap.set(tm, { autoAlpha: 0 })
|
||||||
|
|
||||||
|
// 初始隐藏需要向上浮现的小字文本节点
|
||||||
|
gsap.set(fadeUpItems, { y: 20, autoAlpha: 0 })
|
||||||
|
|
||||||
// 执行入场动画:将 Hero 整体容器从屏幕下方(yPercent: 100)滑入屏幕(yPercent: 0)
|
// 执行入场动画:将 Hero 整体容器从屏幕下方(yPercent: 100)滑入屏幕(yPercent: 0)
|
||||||
gsap.to(heroRef.value, {
|
gsap.to(heroRef.value, {
|
||||||
yPercent: 0,
|
yPercent: 0,
|
||||||
@@ -62,6 +68,13 @@ const play = () => new Promise<void>((resolve) => {
|
|||||||
duration: 0.6,
|
duration: 0.6,
|
||||||
ease: 'power2.out'
|
ease: 'power2.out'
|
||||||
}, '-=0.4')
|
}, '-=0.4')
|
||||||
|
.to(fadeUpItems, {
|
||||||
|
y: 0,
|
||||||
|
autoAlpha: 1,
|
||||||
|
duration: 0.8,
|
||||||
|
ease: 'power3.out',
|
||||||
|
stagger: 0.04 // 稍微错开一点点时间,或者设为 0 完全同时
|
||||||
|
}, '-=0.6') // 让它们在大字动画快结束时出现
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onComplete: resolve,
|
onComplete: resolve,
|
||||||
@@ -198,19 +211,20 @@ defineExpose({ play })
|
|||||||
<div class="flex flex-col md:flex-row justify-between w-full">
|
<div class="flex flex-col md:flex-row justify-between w-full">
|
||||||
<!-- Top Left: Services List -->
|
<!-- Top Left: Services List -->
|
||||||
<div class="flex flex-col gap-2 font-bold text-base md:text-[1rem] tracking-tight leading-[1.5]">
|
<div class="flex flex-col gap-2 font-bold text-base md:text-[1rem] tracking-tight leading-[1.5]">
|
||||||
<p>{{ t('hero.services.webDesign') }}</p>
|
<p class="hero-fade-up will-change-transform">{{ t('hero.services.webDesign') }}</p>
|
||||||
<p>{{ t('hero.services.socialMedia') }}</p>
|
<p class="hero-fade-up will-change-transform">{{ t('hero.services.socialMedia') }}</p>
|
||||||
<p>{{ t('hero.services.marketing') }}</p>
|
<p class="hero-fade-up will-change-transform">{{ t('hero.services.marketing') }}</p>
|
||||||
<p>{{ t('hero.services.development') }}</p>
|
<p class="hero-fade-up will-change-transform">{{ t('hero.services.development') }}</p>
|
||||||
<p>{{ t('hero.services.seo') }}</p>
|
<p class="hero-fade-up will-change-transform">{{ t('hero.services.seo') }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Top Right: Description and Button -->
|
<!-- Top Right: Description and Button -->
|
||||||
<div class="flex flex-col gap-8 max-w-[22rem] mt-10 md:mt-0 text-left">
|
<div class="flex flex-col gap-8 max-w-[22rem] mt-10 md:mt-0 text-left">
|
||||||
<p class="font-bold text-[1rem] leading-[1.5] tracking-tight">
|
<p class="hero-fade-up will-change-transform font-bold text-[1rem] leading-[1.5] tracking-tight">
|
||||||
{{ t('hero.description') }}
|
{{ t('hero.description') }}
|
||||||
</p>
|
</p>
|
||||||
<div>
|
<div class="hero-fade-up will-change-transform">
|
||||||
|
<NuxtLink to="/contact">
|
||||||
<button
|
<button
|
||||||
ref="talkBtnRef"
|
ref="talkBtnRef"
|
||||||
@mouseenter="onTalkHover"
|
@mouseenter="onTalkHover"
|
||||||
@@ -245,16 +259,17 @@ defineExpose({ play })
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Middle Section: 4 small dots -->
|
<!-- 中间 Section: 4 small dots -->
|
||||||
<div class="flex justify-between w-full items-start flex-1 mt-16 md:mt-24 mb-6 md:mb-0">
|
<div class="flex justify-between w-full items-start flex-1 mt-16 md:mt-24 mb-6 md:mb-0">
|
||||||
<div class="w-2.5 h-2.5 bg-black rounded-full"></div>
|
<div class="hero-fade-up will-change-transform w-2.5 h-2.5 bg-black rounded-full"></div>
|
||||||
<div class="w-2.5 h-2.5 bg-black rounded-full"></div>
|
<div class="hero-fade-up will-change-transform w-2.5 h-2.5 bg-black rounded-full"></div>
|
||||||
<div class="w-2.5 h-2.5 bg-black rounded-full"></div>
|
<div class="hero-fade-up will-change-transform w-2.5 h-2.5 bg-black rounded-full"></div>
|
||||||
<div class="w-2.5 h-2.5 bg-black rounded-full"></div>
|
<div class="hero-fade-up will-change-transform w-2.5 h-2.5 bg-black rounded-full"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Bottom Section -->
|
<!-- Bottom Section -->
|
||||||
@@ -275,7 +290,7 @@ defineExpose({ play })
|
|||||||
|
|
||||||
<!-- Bottom Right: Studio -->
|
<!-- Bottom Right: Studio -->
|
||||||
<div class="flex flex-col items-start md:items-end mt-4 md:mt-0">
|
<div class="flex flex-col items-start md:items-end mt-4 md:mt-0">
|
||||||
<p class="text-xs md:text-sm font-semibold text-gray-500 mb-2 md:mb-6 mr-1">© {{ new Date().getFullYear() }} {{ t('app.brand') }}™ {{ t('nav.studio') }}</p>
|
<p class="hero-fade-up will-change-transform text-xs md:text-sm font-semibold text-gray-500 mb-2 md:mb-6 mr-1">© {{ new Date().getFullYear() }} {{ t('app.brand') }}™ {{ t('nav.studio') }}</p>
|
||||||
<h2 ref="studioNameRef" class="text-[11vw] md:text-[8vw] font-bold leading-[0.8] tracking-tighter m-0 -mr-1 whitespace-nowrap pt-4 pb-2">
|
<h2 ref="studioNameRef" class="text-[11vw] md:text-[8vw] font-bold leading-[0.8] tracking-tighter m-0 -mr-1 whitespace-nowrap pt-4 pb-2">
|
||||||
<span class="relative inline-flex overflow-hidden">
|
<span class="relative inline-flex overflow-hidden">
|
||||||
<span
|
<span
|
||||||
|
|||||||
Reference in New Issue
Block a user