如何优化JavaScript渐变色彩网格:解决色彩占比、重复及中心色调问题
色彩渐变网格优化方案
问题背景
我用JavaScript创建色彩渐变网格,要求相邻颜色色调相近(比如绿色不能和红色相邻),目前实现了基础效果,但有三个问题待解决:
- 蓝色/红色占比远高于绿色,缺少深绿色;
- 所有颜色需互不相同;
- 网格中心色调为浅色而非深色。
当前实现代码
JavaScript代码
const COLUMNS = 30; const ROWS = 16; const TOTAL = COLUMNS * ROWS; const generateRed = (step) => { return 0 + step * (255 / TOTAL); } const generateGreen = (step) => { return 255 - step * (255 / ROWS); } const generateBlue = (step) => { return 255 - step * (255 / COLUMNS); } function generateColorStrip(row) { const colors = []; for (let column = 0; column < COLUMNS; column++) { const r = generateRed(column * ROWS); const g = generateGreen(row); const b = generateBlue(column); colors.push(`rgb(${r}, ${g}, ${b})`); } return colors; } function generateColorStrips() { let colors = []; for (let row = 0; row < ROWS; row++) { colors = [...colors, ...generateColorStrip(row)] } return colors; } const colors = generateColorStrips(); colors.forEach(color => { const newDiv = document.createElement('div'); newDiv.style.backgroundColor=color; document.body.appendChild(newDiv); document.body.style.gridTemplateColumns = `repeat(${COLUMNS}, auto)`; });
CSS代码
body { display: grid; max-height: 5em; height: 5em; gap: 1px; width: min-content; } div { height: 10px; aspect-ratio: 1; }
优化方案
针对三个问题,改用HSL色彩模型实现更精准的渐变控制(HSL比RGB更容易调节色相、饱和度和亮度的平滑过渡),具体调整如下:
1. 平衡绿色占比,补充深绿色
让色相沿水平+垂直方向覆盖红色(0°)-绿色(120°)-蓝色(240°)全范围,确保绿色有足够占比,同时通过亮度变化生成从浅到深的绿色调。
2. 保证所有颜色互不相同
基于每个单元格的行列坐标生成唯一的HSL参数组合,通过细微的色相、亮度差异确保颜色不重复。
3. 中心色调为浅色
以网格中心为原点,计算单元格到中心的距离,距离越近亮度越高,距离越远亮度越低,实现中心亮、边缘暗的效果。
优化后完整代码
JavaScript代码
const COLUMNS = 30; const ROWS = 16; const CENTER_X = COLUMNS / 2; const CENTER_Y = ROWS / 2; const MAX_DISTANCE = Math.hypot(CENTER_X, CENTER_Y); // 计算单元格到中心的相对距离(范围0-1) const getDistanceFromCenter = (x, y) => { const dx = x - CENTER_X; const dy = y - CENTER_Y; return Math.hypot(dx, dy) / MAX_DISTANCE; }; // 生成唯一HSL颜色 const generateHSL = (x, y) => { // 色相:水平+垂直方向平滑过渡,覆盖红-绿-蓝全色相 const hue = (x / COLUMNS) * 240 + (y / ROWS) * 120; // 饱和度:固定80%保证色彩鲜艳度 const saturation = 80; // 亮度:中心最亮(90%),边缘逐渐变暗(40%) const lightness = 90 - getDistanceFromCenter(x, y) * 50; return `hsl(${hue}, ${saturation}%, ${lightness}%)`; }; // 生成所有网格颜色 const generateColors = () => { const colors = []; for (let y = 0; y < ROWS; y++) { for (let x = 0; x < COLUMNS; x++) { colors.push(generateHSL(x, y)); } } return colors; }; // 渲染网格 const colors = generateColors(); colors.forEach(color => { const newDiv = document.createElement('div'); newDiv.style.backgroundColor = color; document.body.appendChild(newDiv); }); document.body.style.gridTemplateColumns = `repeat(${COLUMNS}, auto)`;
CSS代码(保持不变)
body { display: grid; max-height: 5em; height: 5em; gap: 1px; width: min-content; } div { height: 10px; aspect-ratio: 1; }
效果说明
- 色相沿网格平滑过渡,红、绿、蓝占比均衡,包含从浅绿到深绿的完整色调;
- 每个单元格的HSL参数唯一,所有颜色互不重复;
- 网格中心亮度最高(浅色),向边缘逐渐变暗,完全符合预期效果。
内容的提问来源于stack exchange,提问作者Raphael Aleixo
相关产品推荐
相关产品推荐

