feat(页面): 添加工具页面链接并优化页脚动画效果
在页脚添加工具页面链接,并优化动画效果使用GSAP实现更流畅的过渡。同时为工具数据添加类型定义以提高代码可维护性。 - 在ArcticNewOneFooter.vue中添加工具链接 - 优化GSAP动画配置,使用fromTo实现更精细控制 - 为tools.vue中的工具数据添加ToolItem接口类型 - 添加CSS类实现动画元素的初始状态
This commit is contained in:
@@ -19,23 +19,32 @@ const pagesLinks = [
|
|||||||
{ name: 'nav.news', url: '/news' },
|
{ name: 'nav.news', url: '/news' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const toolLinks = [
|
||||||
|
{ name: 'nav.tools', url: '/tools' },
|
||||||
|
]
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (!footerRef.value) return
|
if (!footerRef.value) return
|
||||||
|
|
||||||
ctx = gsap.context(() => {
|
ctx = gsap.context(() => {
|
||||||
const items = gsap.utils.toArray<HTMLElement>('.animated-item')
|
const items = gsap.utils.toArray<HTMLElement>('.animated-item', footerRef.value)
|
||||||
|
|
||||||
gsap.from(items, {
|
gsap.fromTo(items, {
|
||||||
|
y: 24,
|
||||||
|
autoAlpha: 0,
|
||||||
|
}, {
|
||||||
scrollTrigger: {
|
scrollTrigger: {
|
||||||
trigger: footerRef.value,
|
trigger: footerRef.value,
|
||||||
start: 'top 80%',
|
start: 'top 80%',
|
||||||
toggleActions: 'play none none reverse',
|
toggleActions: 'play none none reverse',
|
||||||
},
|
},
|
||||||
y: 20,
|
y: 0,
|
||||||
opacity: 0,
|
autoAlpha: 1,
|
||||||
duration: 0.6,
|
duration: 0.8,
|
||||||
stagger: 0.1,
|
stagger: 0.085,
|
||||||
ease: 'power3.out'
|
ease: 'power3.out',
|
||||||
|
immediateRender: false,
|
||||||
|
overwrite: 'auto',
|
||||||
})
|
})
|
||||||
}, footerRef.value)
|
}, footerRef.value)
|
||||||
})
|
})
|
||||||
@@ -50,10 +59,10 @@ onUnmounted(() => {
|
|||||||
<div class="max-w-[1440px] mx-auto">
|
<div class="max-w-[1440px] mx-auto">
|
||||||
<!-- Top Section -->
|
<!-- Top Section -->
|
||||||
<div class="flex flex-col md:flex-row justify-between items-start md:items-end gap-8 mb-16">
|
<div class="flex flex-col md:flex-row justify-between items-start md:items-end gap-8 mb-16">
|
||||||
<h2 class="text-3xl md:text-4xl lg:text-[44px] font-normal tracking-normal !leading-[1.4] max-w-none whitespace-pre-line">
|
<h2 class="animated-item text-3xl md:text-4xl lg:text-[44px] font-normal tracking-normal !leading-[1.4] max-w-none whitespace-pre-line">
|
||||||
{{ t('footer.title') }}
|
{{ t('footer.title') }}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="inline-flex items-center shrink-0">
|
<div class="animated-item inline-flex items-center shrink-0">
|
||||||
<AnimatedButton
|
<AnimatedButton
|
||||||
:text="t('footer.collaborate')"
|
:text="t('footer.collaborate')"
|
||||||
to="/contact"
|
to="/contact"
|
||||||
@@ -63,7 +72,7 @@ onUnmounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Divider -->
|
<!-- Divider -->
|
||||||
<hr class="border-white/10 w-full mb-16" />
|
<hr class="animated-item border-white/10 w-full mb-16" />
|
||||||
|
|
||||||
<!-- Bottom Section -->
|
<!-- Bottom Section -->
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2">
|
<div class="grid grid-cols-1 lg:grid-cols-2">
|
||||||
@@ -103,7 +112,7 @@ onUnmounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right Column -->
|
<!-- Right Column -->
|
||||||
<div class="flex flex-col gap-[50px] lg:pl-16">
|
<div class="flex flex-col gap-10 lg:pl-16">
|
||||||
|
|
||||||
<!-- Links Grid (Top Half) -->
|
<!-- Links Grid (Top Half) -->
|
||||||
<div>
|
<div>
|
||||||
@@ -119,6 +128,19 @@ onUnmounted(() => {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul class="space-y-3">
|
||||||
|
<li v-for="link in toolLinks" :key="link.name" class="animated-item">
|
||||||
|
<NuxtLink :to="link.url" class="group flex items-center overflow-hidden text-[16px] font-bold text-white/80 hover:text-white transition-colors" style="justify-content: flex-start;">
|
||||||
|
<div class="flex items-center transition-transform duration-300 group-hover:translate-x-0 -translate-x-[21px] pr-[21px]">
|
||||||
|
<span class="mr-[10px] h-[11px] w-[11px] rounded-full bg-white shrink-0"></span>
|
||||||
|
<span>{{ t(link.name) }}</span>
|
||||||
|
</div>
|
||||||
|
</NuxtLink>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Contact / Location / Social Grid (Bottom Half) -->
|
<!-- Contact / Location / Social Grid (Bottom Half) -->
|
||||||
<!-- Contacts Row -->
|
<!-- Contacts Row -->
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-8">
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-8">
|
||||||
@@ -180,3 +202,12 @@ onUnmounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.animated-item {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
transform: translate3d(0, 24px, 0);
|
||||||
|
will-change: transform, opacity;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
+9
-1
@@ -124,7 +124,15 @@ onBeforeUnmount(() => {
|
|||||||
cardsCtx?.revert()
|
cardsCtx?.revert()
|
||||||
})
|
})
|
||||||
|
|
||||||
const toolsData = [
|
interface ToolItem {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
url: string
|
||||||
|
icon: string
|
||||||
|
color: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const toolsData: ToolItem[] = [
|
||||||
{
|
{
|
||||||
id: 'drawio',
|
id: 'drawio',
|
||||||
name: 'Drawio',
|
name: 'Drawio',
|
||||||
|
|||||||
Reference in New Issue
Block a user