推荐使用gsap.matchMedia()在 3.11.0+ 版本中
ScrollTrigger.matchMedia
ScrollTrigger.matchMedia( vars:Object )
[已弃用]允许您设置仅适用于特定视口大小的 ScrollTriggers(使用媒体查询)。
参数
vars: 对象
包含每个媒体查询键的配置对象,例如
{"(min-width: 800px)": function() { ... }, "(max-width: 799px)": function() { ... }}
一个特殊的"all"
键可用于需要持续存在的 ScrollTriggers。
允许你设置仅适用于特定视口大小(使用媒体查询)的 ScrollTriggers。其实非常简单——传入一个配置对象,为每个类似 "(min-width: 800px)" 的媒体查询键提供一个对应的函数,当该媒体查询匹配时运行此函数。在该函数中完成你的所有设置任务即可。在此函数内部创建的任何 ScrollTriggers 都会在该媒体查询不再匹配时自动还原并销毁!如果 ScrollTrigger 绑定了动画,也会一并被还原和销毁。
没有matchMedia(),你将需要:
- 手动设置你自己的window.matchMedia()功能、处理程序等。
- 手动kill()销毁每个不适用于新尺寸的 ScrollTrigger。这意味着你需要要么将它们保存在一个数组中,要么使用ScrollTrigger.getAll().
- 确保创建新的 ScrollTriggers 之前,先将内容恢复到固定前、ScrollTrigger 应用前的状态,以防止污染。例如,如果你固定了某个元素,它必须被取消固定并放回正常的文档流中,以便你的 CSS 规则能正确影响它。
但使用ScrollTrigger.matchMedia()
,它可以自动处理大部分工作。
配置对象中的每个键正是你可以传递给原生window.matchMedia().
每个媒体查询的函数会在其变为活动状态(匹配)时调用。因此,如果用户多次调整浏览器窗口大小跨越断点来回切换,该函数会被相应调用多次。请注意,当媒体查询变为非活动状态(不再匹配)时,相关联的所有 ScrollTriggers 都会被还原并销毁,因此你无需担心它们堆积。
简单结构
ScrollTrigger.matchMedia({
// large
"(min-width: 960px)": function () {
// setup animations and ScrollTriggers for screens 960px wide or greater...
// These ScrollTriggers will be reverted/killed when the media query doesn't match anymore.
},
// medium
"(min-width: 600px) and (max-width: 959px)": function () {
// The ScrollTriggers created inside these functions are segregated and get
// reverted/killed when the media query doesn't match anymore.
},
// small
"(max-width: 599px)": function () {
// The ScrollTriggers created inside these functions are segregated and get
// reverted/killed when the media query doesn't match anymore.
},
// all
all: function () {
// ScrollTriggers created here aren't associated with a particular media query,
// so they persist.
},
});
演示
加载中...
您还可以使用ScrollTrigger.saveStyles()记录将来可能受动画影响的元素当前的内联样式。这样,当 ScrollTrigger 内部为此媒体查询还原更改时,它会相应地还原这些内联样式。例如,如果你的元素初始没有内联样式,但随后你对其透明度和 "x" 位置做了动画,那么该元素将具有 "opacity" 和 "transform" 内联样式(即使你倒带了补间动画也是如此),这将覆盖其他 CSS 规则。这个机制可以解决这个问题。
示例代码
// record the initial inline CSS for these elements so that ScrollTrigger can revert them even if animations add inline styles later
ScrollTrigger.saveStyles(".panel, #logo"); // if you put this INSIDE one of the functions, it'll only revert the recorded elements when that media query no longer matches. You can use ScrollTrigger.saveStyles() in multiple places.
ScrollTrigger.matchMedia({
// desktop
"(min-width: 800px)": function () {
gsap.to(".panel", {
xPercent: -100,
scrollTrigger: {
trigger: ".panel",
scrub: 1,
pin: true,
end: "+=500",
},
});
},
// mobile
"(max-width: 799px)": function () {
gsap.to("#logo", {
scale: 0.5,
scrollTrigger: {
trigger: ".nav-bar",
start: "top top",
toggleActions: "play none reverse none",
},
});
},
// all
all: function () {
gsap.set(".photo", { opacity: 0 });
ScrollTrigger.batch(".photo", {
onEnter: (elements) =>
gsap.to(elements, { opacity: 1, stagger: 0.1, overwrite: true }),
});
},
});
清理函数
你可以[可选地]返回一个函数它将在该断点不再匹配时被调用,以便你可以执行自定义清理例程,例如销毁非 ScrollTrigger 相关的其他动画。例如:
ScrollTrigger.matchMedia({
// desktop
"(min-width: 800px)": function () {
// ScrollTrigger (this automatically gets killed when the breakpoint no longer matches...
gsap.to(".panel", {
xPercent: -100,
scrollTrigger: {
trigger: ".panel",
scrub: 1,
end: "+=500",
},
});
// other animations that aren't ScrollTrigger-related...
let tl = gsap.timeline();
tl.to(".box", { rotation: 360 }).to(".box", { y: 100 });
// THIS IS THE KEY! Return a function that'll get called when the breakpoint no longer matches so we can kill() the animation (or whatever)
return function () {
tl.kill();
// other cleanup code can go here.
};
},
});
请记住,当媒体查询不再匹配时,ScrollTrigger 会自动销毁在该媒体查询函数内部创建的所有 ScrollTriggers,因此你只需要为那些不直接与 ScrollTrigger 相关的内容编写清理函数即可。与特定 ScrollTrigger 关联的动画也将在媒体查询不再匹配时连同 ScrollTrigger 一起销毁。任意数量(或全部)的媒体查询都可以返回一个函数。
移动设备似乎不起作用?
尝试在你的代码中添加以下内容:
:<meta name="viewport" content="width=device-width, initial-scale=1">
ScrollTrigger.matchMedia() 是在 GSAP 中新增的3.4.0。清理函数返回功能是在3.5.0 版本中新增的。