能否用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
相关产品推荐
相关产品推荐

