refactor(layout): 优化 hero 区域滚动效果和样式
移除 hero 区域的顶部 margin 控制,改为使用 transform 实现平滑滚动 简化滚动逻辑,调整 hero 区域在不同页面的显示效果 更新 CSS 变量定义,移除无用样式
This commit is contained in:
@@ -49,7 +49,7 @@
|
||||
|
||||
<!-- Hero 区域 -->
|
||||
<div class="hero" :class="{ 'small-hero': classsmallhero }" v-if="windowwidth"
|
||||
:style="{ marginTop: heroMarginTop, marginBottom: heroMarginBottom, transform: heroTransform, transition: 'all 0.3s ease' }">
|
||||
:style="{ marginBottom: heroMarginBottom, transform: heroTransform }">
|
||||
<h1 class="typewriter">{{ heroText }}</h1>
|
||||
</div>
|
||||
|
||||
@@ -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,7 +397,7 @@ const updateNavbarStyle = (scrollY: number) => {
|
||||
const handleRouteChange = () => {
|
||||
// 重新解析路由路径
|
||||
rpsliturl = route.path.split('/');
|
||||
|
||||
console.log(rpsliturl);
|
||||
// 更新页面相关状态
|
||||
updatePageState();
|
||||
setActiveIndex(rpsliturl[1]);
|
||||
@@ -434,23 +411,18 @@ const handleRouteChange = () => {
|
||||
// 首页启动打字机效果
|
||||
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
|
||||
);
|
||||
</script>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/* 打字机效果 */
|
||||
|
||||
Reference in New Issue
Block a user