与滚动相关的动画已在网络上使用多年。 近年来,它们开始变得越来越普遍,也许部分原因是设备性能更高,因此能够处理更多动画。
存在许多与滚动相关的技术,因此本文的目的是概述这些技术并提供工具来帮助您选择最适合您的技术。 我认为这些技术可以分为两大类:用于 **特定滚动相关行为** 的技术和用于 **通用滚动相关行为** 的技术。
用于特定滚动相关行为的技术
现代浏览器支持一些简单的原生 CSS 滚动效果。 在某些有限的用例中,它们足以满足您的滚动动画需求。
position: sticky;
如果您只需要元素在滚动页面的一部分时保持在同一位置,使用 position: sticky
是一个不错的选择。 它很简单,并且内置在现代浏览器中。 也就是说,IE 支持和某些移动浏览器需要 polyfill。 有关详细概述,请查看 Preethi 的 这篇文章。
CSS视差
与其说这是一项技术,不如说是一种技巧,但它对于简单的视差效果非常方便,在这些效果中,您希望页面的不同部分在滚动时以不同的速度移动。 DigitalOcean 上有关于该技巧的详细说明,以及 CodePen 上的许多示例,例如 Firewatch 标题。 对我来说,最大的缺点是很难理解要使用哪些值来设置透视和转换以获得完全正确的视差效果。
CSS 滚动捕捉点
滚动捕捉点允许浏览器在用户完成正常滚动后捕捉到您设置的特定滚动位置。 这对于将某些元素保持在视野中很有帮助。 但是,API 仍然 处于变化中,因此请注意使用最新的 API,并注意在生产环境中依赖它。 Max Kohler 的 这篇 CSS-Tricks 文章 是目前了解它的一个好地方。
平滑滚动
使用 JavaScript 中的 window.scrollTo()
甚至 CSS 中的 scroll-behavior
属性,从页面内的部分跳转到部分时,原生支持平滑滚动。 目前,并非所有浏览器都原生支持使鼠标滚轮操作平滑的通用平滑滚动。 有各种 JavaScript 库尝试为鼠标滚轮操作添加平滑滚动支持,但我还没有找到一个没有错误并且与所有其他滚动技术都能很好地配合的库。 此外,平滑滚动 并不总是好的。
用于通用滚动行为的技术
目前,没有办法使用纯 CSS 创建或触发基于滚动位置的通用动画(尽管有一个 提案 可以支持 CSS 中某些形式的基于滚动的通用动画在遥远的未来)或浏览动画的一部分。 因此,如果您想在滚动时动画化元素,您将需要使用至少一些 JavaScript 来创建您想要的效果。 使用 JavaScript 在滚动时触发动画有两种主要方法:使用 **交集观察者** 和使用 **scroll
事件**。
IntersectionObserver
交集观察者 非常适合您只需要与元素在视口中是否可见以及可见多少相关的动画信息的情况。 这使得它们成为揭示动画的良好选择。 即使那样,使用交集观察者也有一些事情很难(但并非不可能),例如根据元素进入视窗的方向触发不同的动画。 如果您想在元素处于开始和结束点之间且不重叠时进行任何滚动动画,交集观察者也没有太大帮助。
scroll
事件
使用 使用滚动事件将使您在控制滚动时的动画方面拥有最大的自由。 它允许您在滚动时影响元素,无论它在视口中处于何处,并根据您的项目需要设置起点和终点。
话虽如此,如果它没有被正确地节流并且没有一个方便的 API 来创建特定的行为,它也会对性能造成巨大影响。 这就是为什么使用一个好的滚动库通常很有帮助,它可以为您处理节流并为您提供一个更方便的 API 来使用。 有些甚至可以为您处理许多调整大小问题!
创建通用滚动行为的工具
有一些全面的滚动库试图让您完全控制滚动时的动画,而无需您自己执行所有计算。
ScrollMagic
ScrollMagic 提供了一个相对简单的 API 来创建滚动时的各种效果,并且可以与 GSAP 和 Velocity.js 等不同的动画库挂钩。 但是,它在过去几年中维护得越来越少,这导致了 ScrollScene 的创建。
ScrollScene
ScrollScene 本质上是一个包装器,旨在使 ScrollMagic 和/或交叉观察者更易于使用。它使用 ScrollMagic 的自定义、维护更好的版本,并添加了其他功能,例如视频播放、场景初始化断点和场景持续时间断点。它还利用了 GSAP。
ScrollTrigger
ScrollTrigger 是 GSAP 的官方 GreenSock 插件。它具有 众多功能,并且拥有任何滚动库中最易于使用的 API(至少对我来说是这样)。使用它,您可以完全控制定义滚动动画的开始和结束位置,在滚动时动画化任何内容(WebGL、canvas、SVG、DOM,等等),在动画运行时将元素固定到位,等等。您甚至可以将其连接到平滑滚动库,它们将完美地协同工作。此外,它还拥有 GreenSock 的支持以及 GreenSock 论坛。
值得一提的是:Locomotive Scroll
虽然它没有试图成为像上面提到的其他库那样全面的滚动库,但 Locomotive Scroll 专注于提供自定义平滑滚动。您还可以通过添加数据属性来动画化 DOM 对象的某些属性,或者挂钩到 onscroll
事件来动画化其他类型的对象。
总结
对于某些特定的滚动动画效果,例如粘性定位和视差,CSS 技术可能就足够了,至少在使用不支持这些属性的浏览器的 polyfill 时是这样。
我通常建议使用 GSAP 的 ScrollTrigger,因为它可以完成 CSS 属性所能做的一切,以及更多。ScrollTrigger 将处理浏览器支持和计算,以便您可以专注于动画!
下面是一个表格,说明您可以使用哪些工具来创建特定的效果
ScrollTrigger | Locomotive Scroll | ScrollScene | ScrollMagic | 交叉观察者 | 平滑滚动 | CSS 滚动捕捉点 | CSS 视差 | position: sticky | |
---|---|---|---|---|---|---|---|---|---|
固定 | ✅ | ⚪️ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ |
视差效果 | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ |
使用缓动滚动动画 | ✅ | ⚪️ | ⚪️ | ⚪️ | ⚪️ | ❌ | ❌ | ⚪️ | ❌ |
捕捉滚动位置 | ✅ | ⚪️ | ⚪️ | ⚪️ | ⚪️ | ❌ | ✅ | ❌ | ❌ |
平滑滚动 | ⚪️ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
动态批处理/交错 | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
支持水平滚动效果 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
下面是一个表格,比较了滚动技术的其他各个方面
ScrollTrigger | Locomotive Scroll | ScrollScene | ScrollMagic | 交叉观察者 | 平滑滚动 | CSS 滚动捕捉点 | CSS 视差 | position: sticky | |
---|---|---|---|---|---|---|---|---|---|
可在生产环境中使用(良好的浏览器支持) | ✅ | ⚪️ | ✅ | ✅ | ⚪️ | ⚪️ | ⚪️ | ✅ | ⚪️ |
动画完全自由 | ✅ | ⚪️ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
维护 | ✅ | ✅ | ✅ | ❌ | n/a | n/a | n/a | n/a | n/a |
适用于 DOM、Canvas、WebGl、SVG | ✅ | ⚪️ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
易于与调整大小一起使用 | ✅ | ✅ | ✅ | ⚪️ | ✅ | ✅ | ✅ | ✅ | ✅ |
将动画限制在相关部分 | ✅ | ❌ | ⚪️ | ⚪️ | ✅ | ✅ | ✅ | ❌ | ✅ |
方向感知 | ✅ | ⚪️ | ✅ | ✅ | ⚪️ | ❌ | ❌ | ❌ | ❌ |
原生技术 | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
⚪️ = 部分支持
❌ = 否
说到 ScrollTrigger,我一直收藏了许多很棒的推文,里面都是人们自它不久前发布以来所制作的演示。
https://twitter.com/hexagoncircle/status/1267527169128816640?s=12
https://twitter.com/W_R_Chase/status/1269987309711212544
https://twitter.com/petebarr/status/1268877832014438400
https://twitter.com/pixelia_me/status/1267570602266763269
https://twitter.com/mariod/status/1267842581985210369
我的建议:我制作了一个微妙的徽标动画,在网站上使用 CSS3D,当我们开始滚动时:https://xem.github.io
希望您不需要滚动这些表格才能看到 ScrollTrigger 的好处。;-)
已修复!
感谢分享!
也许我理解错了,但为什么不提供实际的示例,而不是使用 js 来展示效果?您可以只使用 gif 或视频来做到这一点吗?
我制作了这些演示,因为我希望内容简化,以便专注于效果本身。我制作了演示的视频,以便在文章中使用,但 CSS-Tricks 的人认为演示更好,所以我接受了他们认为最好的。:)