refactor(页面动画): 优化首页动画元素引用和初始化逻辑

移除未使用的 introCharRefs 引用,改用 gsap.utils.toArray 获取字符元素
将 '.hero-intro-tm' 选择器结果缓存为 tmElement 避免重复查询
为静态元素添加 v-once 指令提升性能
调整部分元素的初始 opacity 和 visibility 状态
This commit is contained in:
2026-04-26 21:58:25 +08:00
parent c1ab766c49
commit af898f1cfe
+14 -10
View File
@@ -54,7 +54,6 @@ const loaderRef = ref<HTMLElement | null>(null)
const loaderBarRef = ref<HTMLElement | null>(null)
const introRef = ref<HTMLElement | null>(null)
const introTitleRef = ref<HTMLElement | null>(null)
const introCharRefs = ref<HTMLElement[]>([])
const heroStageRef = ref<HTMLElement | null>(null)
const heroRef = ref<HTMLElement | null>(null)
const heroPanelRef = ref<HTMLElement | null>(null)
@@ -96,8 +95,9 @@ onMounted(() => {
}
const introCharElements = gsap.utils.toArray('.hero-intro-char', introElement)
const tmElement = introElement.querySelector('.hero-intro-tm')
if (introCharElements.length === 0) {
if (introCharElements.length === 0 || !tmElement) {
return
}
@@ -210,10 +210,10 @@ onMounted(() => {
y: 0,
autoAlpha: 1,
})
.set('.hero-intro-tm', {
.set(tmElement, {
autoAlpha: 0,
})
.fromTo(gsap.utils.toArray('.hero-intro-char', introElement), {
.fromTo(introCharElements, {
yPercent: 110,
y: 0,
}, {
@@ -222,7 +222,7 @@ onMounted(() => {
duration: 0.75,
stagger: 0.055,
})
.to('.hero-intro-tm', {
.to(tmElement, {
autoAlpha: 1,
duration: 0.4,
ease: 'power2.out',
@@ -271,7 +271,7 @@ onMounted(() => {
gsap.set(introTitleElement, { y: 0, autoAlpha: 1 })
// 强制清除 CSS 中的 translateY 像素值,避免被 GSAP 解析为固定 y 像素导致一直不可见
gsap.set(introCharElements, { y: 0, yPercent: 110 })
gsap.set('.hero-intro-tm', { autoAlpha: 0 })
gsap.set(tmElement, { autoAlpha: 0 })
gsap.set(heroElement, { yPercent: 100 })
if (topHeader) {
gsap.set(topHeader, { yPercent: -140, autoAlpha: 0 })
@@ -336,7 +336,7 @@ onBeforeUnmount(() => {
:data-demo-user="demoUserName"
:data-demo-user-role="demoUserRole"
>
<div ref="loaderRef" class="page-loader" aria-hidden="true">
<div ref="loaderRef" class="page-loader" aria-hidden="true" v-once>
<div class="page-loader-content">
<p>Loading</p>
<span class="page-loader-line">
@@ -346,14 +346,14 @@ onBeforeUnmount(() => {
</div>
<div ref="introRef" class="hero-intro" aria-hidden="true">
<h1 ref="introTitleRef" class="hero-intro-title" :aria-label="introTitle">
<h1 ref="introTitleRef" class="hero-intro-title" :aria-label="introTitle" v-once>
<span class="hero-intro-word">
<span
v-for="(letter, index) in introLetters"
:key="`${letter}-${index}`"
class="hero-intro-char-wrap"
>
<span ref="introCharRefs" class="hero-intro-char">{{ letter }}</span>
<span class="hero-intro-char">{{ letter }}</span>
</span>
<span class="hero-intro-tm">TM</span>
</span>
@@ -365,7 +365,7 @@ onBeforeUnmount(() => {
class="hero-stage"
:style="{ '--hero-pin-distance': `${heroPinDistance}px` }"
>
<section ref="heroRef" class="hero-section">
<section ref="heroRef" class="hero-section" v-once>
<div class="hero-backdrop" aria-hidden="true">
<div
v-for="column in heroGalleryColumns"
@@ -455,6 +455,8 @@ onBeforeUnmount(() => {
overflow: hidden;
color: #fff;
background: #000;
opacity: 0;
visibility: hidden;
will-change: transform;
}
@@ -495,6 +497,8 @@ onBeforeUnmount(() => {
font-weight: 700;
letter-spacing: -0.02em;
line-height: 1;
opacity: 0;
visibility: hidden;
}
.hero-stage {