From 3173bd3cd6a95dac74bfeef9efe5028bb39b8616 Mon Sep 17 00:00:00 2001 From: chenchun Date: Sun, 26 Apr 2026 19:26:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E5=85=A5=E5=9C=BA=E5=8A=A8=E7=94=BB=E5=B9=B6=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 lenis.client.ts 中提供 lenis 实例供全局使用 - 添加首页入场动画,包含字母动画和过渡效果 - 优化滚动行为,入场期间锁定滚动 - 修复自定义光标初始位置问题 - 调整页面布局样式,隐藏滚动条 - 更新头部组件类名以匹配新设计 --- app/assets/css/tailwind.css | 18 ++ app/components/layouts/ArcticNewOneCursor.vue | 25 +- app/components/layouts/ArcticNewOneHeader.vue | 2 +- app/pages/index.vue | 240 +++++++++++++++--- app/plugins/lenis.client.ts | 6 + 5 files changed, 248 insertions(+), 43 deletions(-) diff --git a/app/assets/css/tailwind.css b/app/assets/css/tailwind.css index da0e9a3..e462bf9 100644 --- a/app/assets/css/tailwind.css +++ b/app/assets/css/tailwind.css @@ -9,6 +9,24 @@ html, body { + max-width: 100%; + overflow-x: clip; background: #fff; } + + html { + scrollbar-width: none; + } + + html::-webkit-scrollbar { + width: 0; + height: 0; + } + + /* 首页入场动画期间首帧就隐藏滚动条,避免黑色遮罩边缘露出白色滚动槽。 */ + html.is-home-intro-active, + html.is-home-intro-active body { + overflow: hidden; + background: #000; + } } diff --git a/app/components/layouts/ArcticNewOneCursor.vue b/app/components/layouts/ArcticNewOneCursor.vue index 0b5c2c5..1d9ba7f 100644 --- a/app/components/layouts/ArcticNewOneCursor.vue +++ b/app/components/layouts/ArcticNewOneCursor.vue @@ -31,6 +31,7 @@ let cursorX = 0 let cursorY = 0 let pillWidth = 100 let isPillVisible = false +let hasCursorPosition = false // 查找最近的 `data-cursor-label` 元素,用来判断是否需要显示胶囊态。 const getCursorTarget = (target: EventTarget | null) => { @@ -94,6 +95,10 @@ onMounted(() => { } const showCursor = () => { + if (!hasCursorPosition) { + return + } + gsap.to([horizontalLineRef.value, verticalLineRef.value], { autoAlpha: 1, duration: 0.15, @@ -112,6 +117,7 @@ onMounted(() => { const hideCursor = () => { isPillVisible = false + hasCursorPosition = false gsap.to(allTargets, { autoAlpha: 0, @@ -187,6 +193,7 @@ onMounted(() => { const moveCursor = (event: MouseEvent) => { cursorX = event.clientX cursorY = event.clientY + hasCursorPosition = true showCursor() gsap.set(dotRef.value, { @@ -205,6 +212,10 @@ onMounted(() => { return } + if (!hasCursorPosition) { + moveCursor(event) + } + showPill(target.dataset.cursorLabel || 'Read more') } @@ -221,14 +232,14 @@ onMounted(() => { } window.addEventListener('mousemove', moveCursor) - window.addEventListener('mouseenter', showCursor) + window.addEventListener('mouseenter', moveCursor) window.addEventListener('mouseleave', hideCursor) document.addEventListener('mouseover', handleMouseOver) document.addEventListener('mouseout', handleMouseOut) cleanupCursor = () => { window.removeEventListener('mousemove', moveCursor) - window.removeEventListener('mouseenter', showCursor) + window.removeEventListener('mouseenter', moveCursor) window.removeEventListener('mouseleave', hideCursor) document.removeEventListener('mouseover', handleMouseOver) document.removeEventListener('mouseout', handleMouseOut) @@ -257,6 +268,14 @@ onBeforeUnmount(() => {