如何使用GSAP实现页面滚动时Scrub式动态修改CSS变量--color的值
嘿,我完全懂你想用GSAP的scrub功能实现滚动时动态切换CSS变量--color的需求,这事儿绝对能搞定!我给你一个亲测有效的完整方案,一步步来:
实现思路
核心是利用GSAP的ScrollTrigger插件,把滚动进度和动画进度绑定(也就是scrub模式),然后通过动画RGB颜色的三个通道值,实时组合成完整的rgb()赋值给--color变量。
完整代码实现
1. 基础HTML结构
先引入GSAP和ScrollTrigger,然后给页面加足够多的内容让它能滚动:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Scroll Color Scrub</title> <!-- 引入GSAP核心和ScrollTrigger插件 --> <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js"></script> </head> <body> <div class="page-content"> <h1>滚动页面看看背景色变化~</h1> <p>往下滚到底,背景会从白色变成黑色;往上滚回顶部,又会变回白色</p> <!-- 重复内容让页面有足够滚动高度 --> <p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p> <p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p> <p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p> <p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p> <p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p> <p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p><p>占位内容</p> </div> </body> </html>
2. CSS样式
定义--color变量,把它应用到需要的元素(比如body背景),同时给body设置足够高度确保能滚动:
:root { --color: rgb(255, 255, 255); } body { margin: 0; background-color: var(--color); /* 设置足够的滚动高度,这里用300vh让页面能滚3屏 */ height: 300vh; } .page-content { padding: 2rem; color: #333; }
3. GSAP动画逻辑
注册ScrollTrigger插件,然后创建绑定滚动的动画,拆分RGB通道来实现平滑过渡:
// 必须先注册ScrollTrigger插件,否则scrub功能用不了 gsap.registerPlugin(ScrollTrigger); // 初始化RGB三个通道的初始值为255(白色) gsap.set(':root', { '--color-r': 255, '--color-g': 255, '--color-b': 255 }); // 创建滚动绑定的动画 gsap.to(':root', { // 分别动画三个颜色通道从255降到0 '--color-r': 0, '--color-g': 0, '--color-b': 0, // 动画更新时,把三个通道值组合成完整的RGB赋值给--color onUpdate: function() { const r = Math.floor(gsap.getProperty(':root', '--color-r')); const g = Math.floor(gsap.getProperty(':root', '--color-g')); const b = Math.floor(gsap.getProperty(':root', '--color-b')); gsap.set(':root', { '--color': `rgb(${r}, ${g}, ${b})` }); }, // 绑定滚动触发器 scrollTrigger: { trigger: 'body', // 触发元素设为body start: 'top top', // 滚动开始点:body顶部对齐视口顶部 end: 'bottom bottom', // 滚动结束点:body底部对齐视口底部 scrub: true, // 开启scrub模式,动画进度完全跟随滚动进度 // markers: true, // 调试时可以打开,查看滚动触发的起止位置 } });
为什么这么做?
直接动画整个rgb(255,255,255)字符串的话,GSAP没法正确做数值插值,所以我们把颜色拆成三个单独的数值型CSS变量,让GSAP平滑动画这三个数字,再实时组合成完整的RGB值,这样就能实现从白到黑(反向则从黑到白)的无缝过渡,完全符合你要的scrub效果。
额外提示
- 如果你的页面内容本身就有足够高度,可以去掉
body { height: 300vh; }这行 - 调试时可以把
markers: true打开,能直观看到滚动触发的起止位置,方便调整 - 要是想调整过渡的快慢或者范围,修改ScrollTrigger的
start和end参数就行,比如end: '80% bottom'会让颜色在滚动到页面80%位置就完成变化
内容的提问来源于stack exchange,提问作者Hammaad
相关产品推荐
相关产品推荐

