From 0a738e2074c0578407fb93508c4f9d0e3c18a648 Mon Sep 17 00:00:00 2001 From: chenchun Date: Mon, 27 Apr 2026 21:07:22 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E9=A1=B5=E8=84=9A):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=9A=E8=AF=AD=E8=A8=80=E6=94=AF=E6=8C=81=E5=92=8C=E5=8A=A8?= =?UTF-8?q?=E7=94=BB=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构页脚组件,增加中英文翻译支持 创建 FooterLogo 和 AnimatedButton 通用组件 实现滚动动画和按钮悬停效果 --- app/components/common/AnimatedButton.vue | 98 +++++++++ app/components/common/FooterLogo.vue | 101 +++++++++ app/components/home/HomeHero.vue | 47 +--- app/components/layouts/ArcticNewOneFooter.vue | 207 +++++++++++++++++- i18n/locales/en.json | 11 + i18n/locales/zh.json | 11 + 6 files changed, 435 insertions(+), 40 deletions(-) create mode 100644 app/components/common/AnimatedButton.vue create mode 100644 app/components/common/FooterLogo.vue diff --git a/app/components/common/AnimatedButton.vue b/app/components/common/AnimatedButton.vue new file mode 100644 index 0000000..48144f8 --- /dev/null +++ b/app/components/common/AnimatedButton.vue @@ -0,0 +1,98 @@ + + + \ No newline at end of file diff --git a/app/components/common/FooterLogo.vue b/app/components/common/FooterLogo.vue new file mode 100644 index 0000000..81a4dc1 --- /dev/null +++ b/app/components/common/FooterLogo.vue @@ -0,0 +1,101 @@ + + + \ No newline at end of file diff --git a/app/components/home/HomeHero.vue b/app/components/home/HomeHero.vue index 9b49eeb..308ea99 100644 --- a/app/components/home/HomeHero.vue +++ b/app/components/home/HomeHero.vue @@ -3,6 +3,7 @@ import { onMounted, onBeforeUnmount, ref } from 'vue' import { useNuxtApp } from '#app' import { useI18n } from 'vue-i18n' import gsap from 'gsap' +import AnimatedButton from '~/components/common/AnimatedButton.vue' const { t } = useI18n() @@ -82,6 +83,13 @@ const play = () => new Promise((resolve) => { }) // 设置页面向下滚动时的视差缩放逻辑(绑定到 Lenis 的平滑滚动数值上) + +onMounted(() => { + // 组件挂载时,先将整个 Hero 强行置于屏幕下方,等待外部调用 `play()` 才滑入 + if (heroRef.value) gsap.set(heroRef.value, { yPercent: 100 }) + // 初始化滚动监听逻辑 + setupHeroScroll() +}) const setupHeroScroll = () => { if (!heroStageRef.value || !heroPanelRef.value) return @@ -126,44 +134,7 @@ const setupHeroScroll = () => { cleanupHeroScroll = () => gsap.ticker.remove(updateHeroPanelScale) } -const onTalkHover = () => { - if (!talkBtnRef.value) return - const origs = talkBtnRef.value.querySelectorAll('.btn-char-orig') - const clones = talkBtnRef.value.querySelectorAll('.btn-char-clone') - const bg = talkBtnRef.value.querySelector('.btn-bg-hover') - - // 背景从底部滑入 (yPercent: 100 -> 0) - gsap.to(bg, { yPercent: 0, duration: 0.4, ease: 'power3.out', overwrite: true }) - - gsap.to(origs, { yPercent: -100, duration: 0.4, stagger: { amount: 0.2, from: 'start' }, ease: 'power3.out', overwrite: true }) - gsap.to(clones, { yPercent: 0, duration: 0.4, stagger: { amount: 0.2, from: 'start' }, ease: 'power3.out', overwrite: true }) -} - -const onTalkLeave = () => { - if (!talkBtnRef.value) return - const origs = talkBtnRef.value.querySelectorAll('.btn-char-orig') - const clones = talkBtnRef.value.querySelectorAll('.btn-char-clone') - const bg = talkBtnRef.value.querySelector('.btn-bg-hover') - - // 背景向下反向滑出回收 (yPercent: 0 -> 100) - gsap.to(bg, { yPercent: 100, duration: 0.4, ease: 'power3.out', overwrite: true }) - - gsap.to(origs, { yPercent: 0, duration: 0.4, stagger: { amount: 0.2, from: 'end' }, ease: 'power3.out', overwrite: true }) - gsap.to(clones, { yPercent: 100, duration: 0.4, stagger: { amount: 0.2, from: 'end' }, ease: 'power3.out', overwrite: true }) -} - -onMounted(() => { - if (talkBtnRef.value) { - const clones = talkBtnRef.value.querySelectorAll('.btn-char-clone') - const bg = talkBtnRef.value.querySelector('.btn-bg-hover') - gsap.set(clones, { yPercent: 100 }) - gsap.set(bg, { yPercent: 100 }) - } - // 组件挂载时,先将整个 Hero 强行置于屏幕下方,等待外部调用 `play()` 才滑入 - if (heroRef.value) gsap.set(heroRef.value, { yPercent: 100 }) - // 初始化滚动监听逻辑 - setupHeroScroll() -}) +// 设置页面向下滚动时的视差缩放逻辑(绑定到 Lenis 的平滑滚动数值上) onBeforeUnmount(() => { cleanupHeroScroll?.() diff --git a/app/components/layouts/ArcticNewOneFooter.vue b/app/components/layouts/ArcticNewOneFooter.vue index a142623..2392194 100644 --- a/app/components/layouts/ArcticNewOneFooter.vue +++ b/app/components/layouts/ArcticNewOneFooter.vue @@ -1,5 +1,208 @@ + + diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 0705288..24b4288 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -25,5 +25,16 @@ }, "description": "No cookie cutter sites. No empty claims. Only practical tools and smart strategies that drive growth and build brands.", "letsTalk": "Let's talk" + }, + "footer": { + "title": "Crafting visuals. Shaping stories.\nLet's create great work together!", + "collaborate": "Let's Collaborate", + "newsletterTitle": "Be the first to know what's new.", + "emailPlaceholder": "E-mail", + "subscribe": "Subscribe", + "newsletterNote": "No noise. Just curated updates.", + "copyright": "© 2026 ArcticNewOne Studio", + "address": "Binhe West Road, Qixingguan District, Bijie City, Guizhou Province", + "wechat": "WeChat" } } diff --git a/i18n/locales/zh.json b/i18n/locales/zh.json index a243134..a711cff 100644 --- a/i18n/locales/zh.json +++ b/i18n/locales/zh.json @@ -25,5 +25,16 @@ }, "description": "拒绝千篇一律的网站。拒绝空洞的承诺。只提供实用的工具和明智的策略,以推动增长并建立品牌。", "letsTalk": "联系我们" + }, + "footer": { + "title": "雕琢视觉,塑造故事。\n让我们共创卓越作品!", + "collaborate": "联系合作", + "newsletterTitle": "抢先获取最新资讯", + "emailPlaceholder": "输入您的邮箱", + "subscribe": "订阅", + "newsletterNote": "无广告干扰。仅提供精选更新。", + "copyright": "© 2026 北极新一工作室", + "address": "贵州省毕节市七星关区滨河西路", + "wechat": "微信" } }