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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:12:50