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

能否用CSS和JS实现类似《Obra Dinn》风格的Dithered动态渐变网站背景?

实现《Obra Dinn》风格抖动渐变背景

完全可以实现这种复古抖动渐变效果,下面给你两种新手友好的方案:纯CSS静态版和CSS+JS动态过渡版。

一、纯CSS静态抖动渐变

从最简单的静态效果入手,核心是用重复线性渐变制作抖动纹理,再和颜色渐变叠加:

/* 抖动渐变背景容器 */
.dither-gradient {
  width: 100vw;
  height: 100vh;
  /* 基础色彩渐变:可自行修改颜色值 */
  background: linear-gradient(135deg, #0a192f 0%, #64ffda 100%);
  /* 叠加抖动纹理 */
  background-image: repeating-linear-gradient(
    45deg,
    rgba(0,0,0,0.1),
    rgba(0,0,0,0.1) 1px,
    transparent 1px,
    transparent 4px
  );
  /* 混合模式让纹理与渐变融合成抖动效果 */
  background-blend-mode: overlay;
}

使用时,只需在HTML中添加<div class="dither-gradient"></div>即可看到效果。

二、CSS+JS动态过渡版

如果需要可过渡的动态效果,用Canvas生成抖动纹理,结合JS控制渐变颜色的动态变化:

1. HTML结构

<canvas id="dither-bg"></canvas>

2. CSS样式

body { margin: 0; }
#dither-bg {
  width: 100vw;
  height: 100vh;
  display: block;
}

3. JS代码(带详细注释)

const canvas = document.getElementById('dither-bg');
const ctx = canvas.getContext('2d');

// 适配窗口大小
function resizeCanvas() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);

// 定义渐变的起始/结束颜色,可自行修改
let colorStart = { r: 10, g: 25, b: 47 };
let colorEnd = { r: 100, g: 255, b: 218 };
let progress = 0; // 过渡进度(0-1)
let isForward = true; // 控制过渡方向

// 绘制抖动渐变的核心函数
function drawDitherGradient() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  // 根据进度计算当前渐变的颜色范围
  const currentStart = {
    r: Math.floor(colorStart.r + (colorEnd.r - colorStart.r) * progress),
    g: Math.floor(colorStart.g + (colorEnd.g - colorStart.g) * progress),
    b: Math.floor(colorStart.b + (colorEnd.b - colorStart.b) * progress)
  };
  const currentEnd = {
    r: Math.floor(colorEnd.r - (colorEnd.r - colorStart.r) * progress),
    g: Math.floor(colorEnd.g - (colorEnd.g - colorStart.g) * progress),
    b: Math.floor(colorEnd.b - (colorEnd.b - colorStart.b) * progress)
  };

  // 用2x2块生成抖动效果,贴近《Obra Dinn》风格
  for (let y = 0; y < canvas.height; y += 2) {
    for (let x = 0; x < canvas.width; x += 2) {
      // 计算当前位置的渐变比例(从左到右)
      const gradientRatio = x / canvas.width;
      // 转换为灰度值,用于抖动判断
      const targetGray = Math.floor(
        (currentStart.r * (1 - gradientRatio) + currentEnd.r * gradientRatio) * 0.299 +
        (currentStart.g * (1 - gradientRatio) + currentEnd.g * gradientRatio) * 0.587 +
        (currentStart.b * (1 - gradientRatio) + currentEnd.b * gradientRatio) * 0.114
      );
      
      // 2x2抖动矩阵:控制黑点分布密度
      const ditherMatrix = [
        [0, 2],
        [3, 1]
      ];
      // 填充2x2块内的每个像素
      for (let dy = 0; dy < 2; dy++) {
        for (let dx = 0; dx < 2; dx++) {
          if (targetGray < ditherMatrix[dy][dx] * 64) {
            ctx.fillStyle = '#000';
          } else {
            ctx.fillStyle = `rgb(${
              currentStart.r * (1 - gradientRatio) + currentEnd.r * gradientRatio
            }, ${
              currentStart.g * (1 - gradientRatio) + currentEnd.g * gradientRatio
            }, ${
              currentStart.b * (1 - gradientRatio) + currentEnd.b * gradientRatio
            })`;
          }
          ctx.fillRect(x + dx, y + dy, 1, 1);
        }
      }
    }
  }

  // 更新过渡进度,实现来回渐变动画
  if (isForward) {
    progress += 0.005;
    if (progress >= 1) isForward = false;
  } else {
    progress -= 0.005;
    if (progress <= 0) isForward = true;
  }

  requestAnimationFrame(drawDitherGradient);
}

// 启动动画
drawDitherGradient();

新手调整提示

  • 纯CSS版修改linear-gradient内的颜色值,就能快速更换渐变色彩
  • JS版可替换ditherMatrix为4x4矩阵,获得更细腻的抖动效果
  • 调整progress += 0.005的数值可以控制动画速度,数值越小动画越慢

内容的提问来源于stack exchange,提问作者LevelHead

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:36:13