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

如何制作随页面滚动变化的渐变背景网站?参考Fireship效果

实现随页面滚动变化的渐变背景(类似Fireship效果)

核心思路

通过监听页面滚动事件,计算滚动进度(0~1的比例值),根据进度实时调整背景渐变的颜色参数,配合CSS过渡实现平滑的视觉变化。


完整实现代码

HTML 结构

<body>
  <div class="content">
    <!-- 填充足够多的内容使页面可滚动 -->
    <h1>滚动查看渐变效果</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    <!-- 重复添加段落或使用长文本确保页面高度足够 -->
  </div>
</body>

CSS 基础样式

body {
  margin: 0;
  min-height: 200vh; /* 强制页面高度超出视口,允许滚动 */
  transition: background 0.3s ease; /* 渐变切换的平滑过渡 */
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); /* 初始渐变 */
}

.content {
  padding: 2rem 4rem;
  color: #fff;
  font-size: 1.2rem;
  max-width: 800px;
  margin: 0 auto;
}

JavaScript 逻辑

const body = document.body;

// 定义不同滚动进度对应的渐变配色节点
const gradientStops = [
  { progress: 0, start: '#667eea', end: '#764ba2' },
  { progress: 0.4, start: '#f093fb', end: '#f5576c' },
  { progress: 0.7, start: '#43e97b', end: '#38f9d7' },
  { progress: 1, start: '#4facfe', end: '#00f2fe' }
];

// 防抖函数:减少滚动事件触发频率,优化性能
function debounce(func, delay = 15) {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}

// 滚动事件处理逻辑
function handleScroll() {
  // 计算滚动进度(0=顶部,1=底部)
  const scrollProgress = window.scrollY / (document.body.scrollHeight - window.innerHeight);

  // 匹配当前进度对应的渐变区间
  let activeGradient;
  for (let i = 0; i < gradientStops.length - 1; i++) {
    const stopPrev = gradientStops[i];
    const stopNext = gradientStops[i + 1];

    if (scrollProgress >= stopPrev.progress && scrollProgress <= stopNext.progress) {
      // 计算当前区间内的过渡比例
      const segmentProgress = (scrollProgress - stopPrev.progress) / (stopNext.progress - stopPrev.progress);
      // 插值计算过渡后的起始/结束颜色
      const startColor = interpolateColor(stopPrev.start, stopNext.start, segmentProgress);
      const endColor = interpolateColor(stopPrev.end, stopNext.end, segmentProgress);
      // 生成最终渐变样式
      activeGradient = `linear-gradient(135deg, ${startColor} 0%, ${endColor} 100%)`;
      break;
    }
  }

  // 应用渐变背景
  if (activeGradient) body.style.background = activeGradient;
}

// 颜色插值辅助函数:实现两种十六进制颜色的平滑过渡
function interpolateColor(colorA, colorB, progress) {
  // 解析十六进制颜色为RGB值
  const [r1, g1, b1] = hexToRgb(colorA);
  const [r2, g2, b2] = hexToRgb(colorB);

  // 计算过渡后的RGB值
  const r = Math.round(r1 + (r2 - r1) * progress);
  const g = Math.round(g1 + (g2 - g1) * progress);
  const b = Math.round(b1 + (b2 - b1) * progress);

  // 转换回十六进制格式
  return rgbToHex(r, g, b);
}

// 十六进制转RGB辅助函数
function hexToRgb(hex) {
  const r = parseInt(hex.slice(1, 3), 16);
  const g = parseInt(hex.slice(3, 5), 16);
  const b = parseInt(hex.slice(5, 7), 16);
  return [r, g, b];
}

// RGB转十六进制辅助函数
function rgbToHex(r, g, b) {
  return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
}

// 绑定防抖后的滚动事件
window.addEventListener('scroll', debounce(handleScroll));

关键细节说明

  1. 滚动进度计算:通过window.scrollY(已滚动距离)除以document.body.scrollHeight - window.innerHeight(剩余可滚动距离),得到0~1的比例值,代表当前滚动位置在整个页面的占比。
  2. 颜色插值:将十六进制颜色转换为RGB数值,通过线性插值计算过渡阶段的颜色值,实现渐变的平滑切换。
  3. 防抖优化:滚动事件会高频触发,使用防抖函数限制处理逻辑的执行频率,避免性能损耗。
  4. CSS过渡:给body的background属性添加过渡效果,让渐变切换更自然。

内容的提问来源于stack exchange,提问作者Kristóf Németh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:46:07