From 0dc24cfa858b2ec6d1d16c79bd69db2024183c2d Mon Sep 17 00:00:00 2001 From: qingfeng1121 Date: Thu, 18 Dec 2025 15:19:46 +0800 Subject: [PATCH] =?UTF-8?q?refactor(layout):=20=E4=BC=98=E5=8C=96=20hero?= =?UTF-8?q?=20=E5=8C=BA=E5=9F=9F=E6=BB=9A=E5=8A=A8=E6=95=88=E6=9E=9C?= =?UTF-8?q?=E5=92=8C=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除 hero 区域的顶部 margin 控制,改为使用 transform 实现平滑滚动 简化滚动逻辑,调整 hero 区域在不同页面的显示效果 更新 CSS 变量定义,移除无用样式 --- src/layouts/MainLayout.vue | 84 ++++++++++++-------------------------- src/styles/MainLayout.css | 10 ++--- 2 files changed, 32 insertions(+), 62 deletions(-) diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 7d84c48..7ab8d45 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -49,7 +49,7 @@
+ :style="{ marginBottom: heroMarginBottom, transform: heroTransform }">

{{ heroText }}

@@ -104,14 +104,14 @@ const classnonsenset = ref(false); const classsmallhero = ref(false); const elrowtop = ref('transparent'); // hero区域的margin值,用于实现滚动时动态变化 -const heroMarginTop = ref('45%'); const heroMarginBottom = ref('45%'); // hero区域的初始margin值,从CSS变量获取 -const initialHeroMargin = 45; +const initialHeroMarginBottom = 45; // hero是否开始向上移动 const heroIsMoving = ref(false); // hero的transform值,用于实现向上移动和吸附效果 -const heroTransform = ref('translateY(0)'); +const heroTransform = ref('translateY(450px)'); +const heroTransformValue = 450; // hero的位置状态:static(静态)、moving(移动中)、sticky(吸附顶部) const heroPosition = ref('static'); @@ -231,7 +231,6 @@ const updateArticleTitle = () => { if (rpsliturl[2] === 'aericletype') { // 按属性类型获取 articledata = globalStore.getValue('attribute')?.name; - console.log('attributeId参数:', articledata); } else if (rpsliturl[2] === 'aericletitle') { // 按标题搜索获取 @@ -354,48 +353,26 @@ const handleScroll = () => { if (rpsliturl[1] === localhome && rpsliturl[2] == undefined) { const scrollY = window.scrollY; const windowHeight = window.innerHeight; - // 计算滚动距离与窗口高度的比例,用于内容渐显 const contentScrollRatio = Math.min(scrollY / windowHeight, 1); // 计算新的底部margin值,从初始值45%逐渐减少到25% - const newMarginBottom = Math.max(initialHeroMargin - (initialHeroMargin * contentScrollRatio), 0); + const newMarginBottom = Math.max(initialHeroMarginBottom - (initialHeroMarginBottom * contentScrollRatio), 0); // 更新hero的底部margin值 heroMarginBottom.value = `${newMarginBottom}%`; - // 顶部margin保持不变 - heroMarginTop.value = `${initialHeroMargin}%`; - - // 内容区域随滚动逐渐显现 - // 当滚动超过50px时开始显示,滚动到一屏高度时完全显示 - iscontentvisible.value = scrollY > 50; - - // 计算hero的移动阶段 - if (scrollY >= 555) { - // 滚动超过555px,标题开始向上移动 - heroIsMoving.value = true; + // 计算新的translateY值,从初始值450px逐渐减少到150px + const translateYValue = Math.max(heroTransformValue - (heroTransformValue * contentScrollRatio * 5), 90); + heroTransform.value = `translateY(${translateYValue}px)`; + // 当滚动超过100px时开始显示,滚动到一屏高度时完全显示 + iscontentvisible.value = scrollY > 100; + // 当滚动超过287px时logo被顶出屏幕 + if (scrollY > 287) { heroPosition.value = 'moving'; - - // 计算移动距离:从0到初始marginTop值(45%) - // 使用滚动距离减去起始位置(555px),除以移动范围(500px),得到移动比例 - const moveScrollRatio = Math.min((scrollY - 555) / 500, 1); - const moveDistance = initialHeroMargin * moveScrollRatio; - heroTransform.value = `translateY(-${moveDistance*10}%)`; - - // 当移动距离达到初始marginTop值时,吸附到顶部 - if (moveScrollRatio >= 1) { - heroPosition.value = 'sticky'; - heroTransform.value = `translateY(-${initialHeroMargin*10}%)`; - } - } else { - // 滚动未超过555px,标题保持静态 - heroIsMoving.value = false; - heroPosition.value = 'static'; - heroTransform.value = 'translateY(0)'; + const translateYValue = Math.min(heroTransformValue - (heroTransformValue * contentScrollRatio * 5), 0); + heroTransform.value = `translateY(${translateYValue / 2}px)`; } - // 控制左侧模块的滚动状态 isScrollingleftmodlue.value = scrollY > 600; } - }; /** @@ -420,37 +397,32 @@ const updateNavbarStyle = (scrollY: number) => { const handleRouteChange = () => { // 重新解析路由路径 rpsliturl = route.path.split('/'); - + console.log(rpsliturl); // 更新页面相关状态 updatePageState(); setActiveIndex(rpsliturl[1]); updateArticleTitle(); - + // 页面跳转后回到顶部 window.scrollTo({ top: 0, behavior: 'smooth' }); - + // 根据是否为首页决定是否启动打字机效果 if (rpsliturl[1] === localhome && rpsliturl[2] == undefined) { // 首页启动打字机效果 startTypewriter(fullHeroText); // 重置hero的margin值为初始值 - heroMarginBottom.value = `${initialHeroMargin}%`; - heroMarginTop.value = `${initialHeroMargin}%`; + heroMarginBottom.value = `${initialHeroMarginBottom}%`; // 重置hero的移动状态 + heroTransform.value = `translateY(${heroTransformValue}px)`; heroIsMoving.value = false; heroPosition.value = 'static'; - heroTransform.value = 'translateY(0)'; // 移动端首页默认显示内容区,桌面端初始隐藏 iscontentvisible.value = window.innerWidth <= 768; } else { - // 非首页直接显示完整文本 iscontentvisible.value = true; - stopTypewriter(); - } - // 不在首页时,hero的margin为0 - if (rpsliturl[1] !== localhome) { - heroMarginBottom.value = '0%'; - heroMarginTop.value = '0%'; + startTypewriter(fullHeroText); + heroMarginBottom.value = `${5}%`; + heroTransform.value = ``; } }; @@ -465,18 +437,17 @@ const initializePage = () => { // 首页启动打字机效果 startTypewriter(fullHeroText); // 重置hero的margin值为初始值 - heroMarginBottom.value = `${initialHeroMargin}%`; - heroMarginTop.value = `${initialHeroMargin}%`; + heroMarginBottom.value = `${initialHeroMarginBottom}%`; // 重置hero的移动状态 heroIsMoving.value = false; heroPosition.value = 'static'; - heroTransform.value = 'translateY(0)'; // 移动端首页默认显示内容区,桌面端初始隐藏 iscontentvisible.value = window.innerWidth <= 768; } else { - // 非首页清空hero内容 - heroText.value = ''; + startTypewriter(fullHeroText); + heroMarginBottom.value = `${2.5}%`; } + }; // ========== 生命周期钩子 ========== @@ -518,8 +489,7 @@ onUnmounted(() => { */ watch( () => route.path, - handleRouteChange, - { immediate: true } // 立即执行一次,确保初始状态正确 + handleRouteChange ); diff --git a/src/styles/MainLayout.css b/src/styles/MainLayout.css index c2ea03b..cb533ad 100644 --- a/src/styles/MainLayout.css +++ b/src/styles/MainLayout.css @@ -21,11 +21,8 @@ /* hero 默认高度 */ --hero-height-small: 100px; /* hero 收缩后高度 */ - --hero-margin: 45% 0; - /* hero 顶边距 */ - --hero-min-margin-top: 45%; - /* hero 最小顶边距 */ - + --hero-margin-top-small: 6%; + /* hero 收缩后顶部外边距 */ /* 标题样式 */ --title-font-size: 3.5rem; /* hero 主标题字号 */ @@ -385,6 +382,9 @@ p { /* hero 收缩状态 */ .hero.small-hero { height: var(--hero-height-small); + margin-top: var(--hero-margin-top-small); + /* 去除 hero 收缩状态下的position */ + position: static; } /* 打字机效果 */