← 返回日志

页面滚动触发动画效果技术选型.

很多framer做的网站都有滚动的动画效果,比如楼层中的一个图片从小变大,然后继续滚动到下一个楼层可以让slider 卡片自动横向滚动,然后继续到下一个楼层滚动出现打字效果等等。

这类随着页面滚动(Scroll-driven)触发或联动的复杂 UX 效果,在 Framer 社区非常流行(通常被称为 Scrollytelling 或 Scroll-linked Animations)。

在前端工程中(特别是像你们常用的 Astro / React / Tailwind 体系),从实现成本、性能表现、控速精度三个维度来看,主流有以下几套成熟的技术方案:

1. 核心技术方案对比

方案类别代表技术/库实现难度性能 (FPS)推荐适用场景
A. 零依赖原生 (CSS 规范)CSS scroll-timeline简单极高 (GPU)简单的滚动缩放、文字打字显示、滚动进度条等
B. 轻量级轻量触发库AOS.js / ScrollReveal / IntersectionObserver极低高滚动到某个位置时“触发一次”的动画(如打字、淡入)
C. 精细平滑联动库 (推荐)Lenis + GSAPScrollTrigger中等高楼层图片缩放、吸顶固定 + 横向滚动卡片 (Horizontal Slider)
D. 声明式/框架专属Framer Motion (React/Next.js)低~中中~高React / Next.js 项目中,追求极快开发效率的场景

2. 经典交互场景的具体实现思路

针对你提到的三个具体效果,前端的标准落地方式如下:

场景一:楼层图片“从小变大”(Scale / Expand on Scroll)

  • 核心原理:将图片容器设为 Sticky 吸顶,随着 scrollTop 的增加,动态改变 scale(0.8 -> 1) 和 border-radius。
  • 最佳方案:
    • 轻量:CSS 原生 animation-timeline: scroll()(针对现代浏览器)。
    • 全兼容:GSAP ScrollTrigger 的 scrub: true(让动画与滚动进度 1:1 强绑定)。
// GSAP 方案示例:图片随滚动变大并撑满屏幕
gsap.to(".hero-image", {
  scale: 1,
  borderRadius: "0px",
  scrollTrigger: {
    trigger: ".image-section",
    start: "top top", // 当楼层顶部到达视口顶部
    end: "+=100%",   // 滚动的距离
    scrub: 1,        // 带有平滑阻尼的滚动联动
    pin: true        // 吸顶固定,直到动画结束
  }
});

场景二:滚动到楼层时,横向 Slider 卡片自动平移(Horizontal Scroll Pin)

  • 核心原理:“假横向,真纵向”。把外层 section 设为 height: 300vh(或者根据卡片总宽度动态计算),将卡片容器 position: sticky 吸顶。当用户向下滚动页面时,实际上是将内层卡片列表沿 X 轴向左平移 transform: translateX(-Xpx)。
  • 最佳方案:GSAP ScrollTrigger (Pin)。这是业界(包括苹果官网、Framer 导出的代码)做横向滚动楼层的绝对标准方案。
// GSAP 方案示例:纵向滚动驱动横向滑动
const cards = document.querySelector(".cards-wrapper");
gsap.to(cards, {
  x: () => -(cards.scrollWidth - window.innerWidth),
  ease: "none",
  scrollTrigger: {
    trigger: ".horizontal-section",
    start: "top top",
    end: () => "+=" + cards.scrollWidth,
    pin: true,     // 固定当前楼层
    scrub: 1,      // 强绑定滚动进度
    invalidateOnRefresh: true,
  }
});

场景三:滚动到楼层时触发“打字效果”(Typewriter Effect)

  • 核心原理:此效果不需要强行与滚动进度 1:1 绑定(不用随着往下滑动逐字出来,那样体验反而很生硬),只需要在进入视口时触发一次打字即可。
  • 最佳方案:IntersectionObserver + Typed.js (或原生 setInterval)。
    • 用 IntersectionObserver 监测该文本楼层是否进入视口 threshold: 0.5(进入 50%)。
    • 触发一次打字动画或 Tailwind 的字数展开动画。

3. 给团队的技术选型建议 (Tech Stack Recommendation)

如果你们的技术栈主打 Astro / Vue / React / Tailwind,建议使用以下组合拳:

  1. 基础平滑滚动:Lenis.js
    • Framer 网站之所以看起来非常优雅,很大一部分原因在于它们使用了平滑阻尼滚动(Smooth Scroll)。
    • 强烈推荐在项目根部引入 Lenis(极轻量,性能远超旧时代的 Locomotive Scroll),它能瞬间赋予网页“Framer 级”的高级滚动手感。
  2. 复杂联动:GSAP + ScrollTrigger
    • 处理横向滚动卡片、吸顶卡片叠楼层(Cards Stacking)、图片放大等交互,GSAP 是性能最稳、功能最全的选择。
  3. 性能与体验防坑指南(UX Guidelines):
    • 移动端降级:横向滚动卡片在手机端(Touch screen)体验通常很差,建议在移动端(< 768px)降级为原生横向滑动(overflow-x: auto + snap-x)或纯纵向平铺。
    • 只用硬件加速属性:滚动联动中只修改 transform (scale, translate) 和 opacity,绝对不要去动 width, height, margin 等会导致重排(Reflow)的属性,否则在低端设备上会导致卡顿。

相关文章 / 延续阅读 →