You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现滚动响应式网格布局遇阻:菜单栏与文字动效需求

解决方案

一、菜单栏滚动缩放实现

核心思路

监听页面滚动事件,通过滚动方向判断,在特定阶段阻止页面默认滚动行为,动态修改菜单栏高度;当高度达到目标值后,恢复页面正常滚动。

代码实现

  1. 更新CSS:
.edge-panel {
  background-color: #eee;
  width: 20%;
  height: 301.5vh;
}

.menu-bar {
  background-color: #23252b;
  width: 30%;
  height: 75vh;
  position: sticky;
  margin-left: 70%;
  margin-top: 150px;
  top: 0;
  transform: translateX(30%);
  transition: height 0.3s ease-out; /* 优化过渡顺滑度 */
}

.menu-bar:hover {
  border: 5px solid #eee;
  transition: border 0.2s ease-in-out;
}

/* 菜单栏收缩状态类 */
.menu-bar--collapsed {
  height: 10vh; /* 自定义目标收缩高度 */
}
  1. HTML结构:
<div class="edge-panel">
  site name here
  <div class="menu-bar" id="menuBar">
    menu here
  </div>
</div>
  1. 原生JS逻辑:
const menuBar = document.getElementById('menuBar');
const initialHeight = 75; // 初始高度(单位:vh)
const collapsedHeight = 10; // 收缩后目标高度(单位:vh)
let currentHeight = initialHeight;
let isCollapsed = false;
let lastScrollTop = 0;

window.addEventListener('scroll', (e) => {
  const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
  const scrollDelta = scrollTop - lastScrollTop;

  // 向下滚动逻辑
  if (scrollDelta > 0) {
    if (!isCollapsed) {
      e.preventDefault();
      // 动态计算高度,确保不低于收缩值
      currentHeight = Math.max(collapsedHeight, currentHeight - scrollDelta * 0.1);
      menuBar.style.height = `${currentHeight}vh`;

      // 达到收缩高度后,恢复页面滚动
      if (currentHeight <= collapsedHeight) {
        isCollapsed = true;
        menuBar.classList.add('menu-bar--collapsed');
      }
    }
  } 
  // 向上滚动逻辑
  else if (scrollDelta < 0) {
    if (isCollapsed) {
      e.preventDefault();
      // 动态计算高度,确保不超过初始值
      currentHeight = Math.min(initialHeight, currentHeight + Math.abs(scrollDelta) * 0.1);
      menuBar.style.height = `${currentHeight}vh`;

      // 恢复初始高度后,恢复页面滚动
      if (currentHeight >= initialHeight) {
        isCollapsed = false;
        menuBar.classList.remove('menu-bar--collapsed');
      }
    }
  }

  lastScrollTop = scrollTop;
}, { passive: false }); // 必须设置该参数才能阻止默认滚动行为

关键说明

  • 通过scrollDelta判断滚动方向,精准控制菜单栏高度变化阶段。
  • 调整scrollDelta * 0.1中的系数,可改变高度变化的灵敏度。
  • passive: false是阻止默认滚动行为的必要配置。

二、单个字母滚动动效实现

核心思路

将每个字母封装为独立DOM元素,监听滚动事件,根据滚动位置为每个字母应用差异化的位移、透明度动画,形成错落的滚动响应效果。

代码示例

  1. HTML结构:
<div class="hero-text">
  <span class="letter" data-delay="0">V</span>
  <span class="letter" data-delay="0.1">R</span>
  <span class="letter" data-delay="0.2">A</span>
  <span class="letter" data-delay="0.3">R</span>
  <span class="letter" data-delay="0.4">L</span>
  <span class="letter" data-delay="0.5">E</span>
  <span class="letter" data-delay="0.6">S</span>
</div>
  1. CSS基础样式:
.hero-text {
  font-size: 8rem;
  font-weight: bold;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.letter {
  display: inline-block;
  transition: transform 0.5s ease-out, opacity 0.5s ease-out;
}
  1. JS动画逻辑:
const letters = document.querySelectorAll('.letter');

window.addEventListener('scroll', () => {
  // 计算滚动进度百分比
  const scrollPercent = window.pageYOffset / (document.documentElement.scrollHeight - window.innerHeight);
  
  letters.forEach(letter => {
    const delay = parseFloat(letter.dataset.delay);
    // 根据滚动进度和延迟值,计算每个字母的位移与透明度
    const translateY = scrollPercent * 200 - delay * 50;
    const opacity = 1 - scrollPercent * 1.5 + delay * 0.5;
    
    letter.style.transform = `translateY(${translateY}px)`;
    letter.style.opacity = Math.max(0, opacity);
  });
});

关键说明

  • 通过data-delay属性为每个字母设置动画延迟,形成错落有致的视觉效果。
  • 基于滚动百分比计算动画参数,滚动距离越大,字母的位移和透明度变化越明显。
  • 可自定义translateY和opacity的计算逻辑,调整动画的强度与方向。

内容的提问来源于stack exchange,提问作者Nickler-sama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 13:54:58