feat: 添加图标库依赖并优化首页按钮动画

添加@iconify-json/ph图标库依赖
在nuxt.config.ts中配置vite优化依赖
更新社交媒体图标为ph:x-logo
实现首页"Talk"按钮的悬停动画效果
This commit is contained in:
2026-04-28 14:40:14 +08:00
parent b71ab1a342
commit dee222648d
5 changed files with 74 additions and 1 deletions
+53
View File
@@ -22,6 +22,57 @@ const studioNameRef = ref<HTMLElement | null>(null)
const talkBtnRef = ref<HTMLElement | null>(null)
let cleanupHeroScroll: (() => void) | null = null
let talkBtnTl: gsap.core.Timeline | null = null
const initTalkButton = () => {
if (!talkBtnRef.value) return
const hoverBg = talkBtnRef.value.querySelector<HTMLElement>('.btn-bg-hover')
const origChars = gsap.utils.toArray<HTMLElement>('.btn-char-orig', talkBtnRef.value)
const cloneChars = gsap.utils.toArray<HTMLElement>('.btn-char-clone', talkBtnRef.value)
if (!hoverBg || !origChars.length || !cloneChars.length) return
gsap.set(hoverBg, { yPercent: 110 })
gsap.set(origChars, { yPercent: 0 })
gsap.set(cloneChars, { yPercent: 110 })
}
const onTalkHover = () => {
if (!talkBtnRef.value) return
const hoverBg = talkBtnRef.value.querySelector<HTMLElement>('.btn-bg-hover')
const origChars = gsap.utils.toArray<HTMLElement>('.btn-char-orig', talkBtnRef.value)
const cloneChars = gsap.utils.toArray<HTMLElement>('.btn-char-clone', talkBtnRef.value)
if (!hoverBg || !origChars.length || !cloneChars.length) return
talkBtnTl?.kill()
talkBtnTl = gsap.timeline({ defaults: { ease: 'power3.out' } })
talkBtnTl
.to(hoverBg, { yPercent: 0, duration: 0.42 }, 0)
.to(origChars, { yPercent: -115, duration: 0.42, stagger: 0.018 }, 0)
.to(cloneChars, { yPercent: 0, duration: 0.42, stagger: 0.018 }, 0)
}
const onTalkLeave = () => {
if (!talkBtnRef.value) return
const hoverBg = talkBtnRef.value.querySelector<HTMLElement>('.btn-bg-hover')
const origChars = gsap.utils.toArray<HTMLElement>('.btn-char-orig', talkBtnRef.value)
const cloneChars = gsap.utils.toArray<HTMLElement>('.btn-char-clone', talkBtnRef.value)
if (!hoverBg || !origChars.length || !cloneChars.length) return
talkBtnTl?.kill()
talkBtnTl = gsap.timeline({ defaults: { ease: 'power3.out' } })
talkBtnTl
.to(hoverBg, { yPercent: 110, duration: 0.42 }, 0)
.to(origChars, { yPercent: 0, duration: 0.42, stagger: 0.018 }, 0)
.to(cloneChars, { yPercent: 110, duration: 0.42, stagger: 0.018 }, 0)
}
// 暴露供外部(如 index.vue)使用的异步播放方法
const play = () => new Promise<void>((resolve) => {
@@ -89,6 +140,7 @@ onMounted(() => {
if (heroRef.value) gsap.set(heroRef.value, { yPercent: 100 })
// 初始化滚动监听逻辑
setupHeroScroll()
initTalkButton()
})
const setupHeroScroll = () => {
if (!heroStageRef.value || !heroPanelRef.value) return
@@ -138,6 +190,7 @@ const setupHeroScroll = () => {
onBeforeUnmount(() => {
cleanupHeroScroll?.()
talkBtnTl?.kill()
})
defineExpose({ play })
@@ -167,7 +167,7 @@ onUnmounted(() => {
<Icon name="ph:instagram-logo" class="w-4 h-4" />
</a>
<a href="#" class="w-10 h-10 rounded-full bg-[#1f1f1f] hover:bg-[#2f2f2f] flex items-center justify-center transition-colors text-white">
<Icon name="pajamas:twitter-x" class="w-3.5 h-3.5" />
<Icon name="ph:x-logo" class="w-4 h-4" />
</a>
<a href="#" class="w-10 h-10 rounded-full bg-[#1f1f1f] hover:bg-[#2f2f2f] flex items-center justify-center transition-colors text-white">
<Icon name="ph:diamond-fill" class="w-4 h-4" />