颜色转换 #
颜色格式概述 #
Web 开发中常用的颜色格式包括 RGB、HEX、HSL 等。
text
┌─────────────────────────────────────────────────────────────┐
│ 颜色格式 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ RGB │ │ HEX │ │ HSL │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ rgb(r,g,b) │ │ #RRGGBB │ │ hsl(h,s,l) │ │
│ │ 0-255 │ │ 00-FF │ │ 0-360,0-100%│ │
│ │ 直观易读 │ │ 简洁常用 │ │ 便于调整 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ RGBA │ │ HSLA │ │ 颜色名 │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ rgba(r,g,b,a)│ │ hsla(h,s,l,a)│ │ red, blue │ │
│ │ 带透明度 │ │ 带透明度 │ │ 预定义颜色 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
基础函数 #
rgb2hex(rgb) #
将 RGB 颜色值转换为 HEX 格式。
javascript
export const rgb2hex = (rgb = []) => {
return '#' + rgb.map(item => {
let value = item.toString(16);
value = value.length === 1 ? `0${value}` : value;
return value;
}).join('');
};
使用示例 #
javascript
import { rgb2hex } from './utils';
console.log(rgb2hex([255, 0, 0]));
console.log(rgb2hex([0, 128, 255]));
console.log(rgb2hex([255, 255, 0]));
console.log(rgb2hex([128, 128, 128]));
console.log(rgb2hex([0, 0, 0]));
console.log(rgb2hex([255, 255, 255]));
hex2rgb(hex) #
将 HEX 颜色值转换为 RGB 格式。
javascript
export const hex2rgb = (hex) => {
let _hex = hex[0] === '#' ? hex.slice(1) : hex;
const [a, b, c, d, e, f] = _hex.split('');
return [parseInt(a + b, 16), parseInt(c + d, 16), parseInt(e + f, 16)];
};
使用示例 #
javascript
import { hex2rgb } from './utils';
console.log(hex2rgb('#ff0000'));
console.log(hex2rgb('#0080ff'));
console.log(hex2rgb('#ffff00'));
console.log(hex2rgb('#808080'));
console.log(hex2rgb('#000000'));
console.log(hex2rgb('#ffffff'));
console.log(hex2rgb('ff0000'));
进阶用法 #
支持简写 HEX #
javascript
const hex2rgbAdvanced = (hex) => {
let _hex = hex[0] === '#' ? hex.slice(1) : hex;
if (_hex.length === 3) {
_hex = _hex.split('').map(c => c + c).join('');
}
const r = parseInt(_hex.slice(0, 2), 16);
const g = parseInt(_hex.slice(2, 4), 16);
const b = parseInt(_hex.slice(4, 6), 16);
return [r, g, b];
};
console.log(hex2rgbAdvanced('#f00'));
console.log(hex2rgbAdvanced('#0ff'));
RGB 与 HSL 互转 #
javascript
const rgb2hsl = (r, g, b) => {
r /= 255;
g /= 255;
b /= 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
case g: h = ((b - r) / d + 2) / 6; break;
case b: h = ((r - g) / d + 4) / 6; break;
}
}
return [
Math.round(h * 360),
Math.round(s * 100),
Math.round(l * 100)
];
};
const hsl2rgb = (h, s, l) => {
h /= 360;
s /= 100;
l /= 100;
let r, g, b;
if (s === 0) {
r = g = b = l;
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [
Math.round(r * 255),
Math.round(g * 255),
Math.round(b * 255)
];
};
console.log(rgb2hsl(255, 0, 0));
console.log(hsl2rgb(0, 100, 50));
颜色亮度调整 #
javascript
const adjustBrightness = (hex, percent) => {
const rgb = hex2rgb(hex);
const adjusted = rgb.map(value => {
const adjusted = Math.round(value * (1 + percent / 100));
return Math.max(0, Math.min(255, adjusted));
});
return rgb2hex(adjusted);
};
console.log(adjustBrightness('#ff0000', 20));
console.log(adjustBrightness('#ff0000', -20));
颜色混合 #
javascript
const blendColors = (color1, color2, ratio = 0.5) => {
const rgb1 = hex2rgb(color1);
const rgb2 = hex2rgb(color2);
const blended = rgb1.map((value, index) => {
return Math.round(value * (1 - ratio) + rgb2[index] * ratio);
});
return rgb2hex(blended);
};
console.log(blendColors('#ff0000', '#0000ff', 0.5));
console.log(blendColors('#ff0000', '#0000ff', 0.25));
生成渐变色 #
javascript
const generateGradient = (startColor, endColor, steps) => {
const colors = [];
for (let i = 0; i < steps; i++) {
const ratio = i / (steps - 1);
colors.push(blendColors(startColor, endColor, ratio));
}
return colors;
};
const gradient = generateGradient('#ff0000', '#0000ff', 5);
console.log(gradient);
生成随机颜色 #
javascript
const randomColor = () => {
return '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0');
};
const randomRgbColor = () => {
return [
Math.floor(Math.random() * 256),
Math.floor(Math.random() * 256),
Math.floor(Math.random() * 256)
];
};
const randomPastelColor = () => {
const r = Math.floor((Math.random() * 128) + 128);
const g = Math.floor((Math.random() * 128) + 128);
const b = Math.floor((Math.random() * 128) + 128);
return rgb2hex([r, g, b]);
};
console.log(randomColor());
console.log(randomPastelColor());
颜色对比度 #
javascript
const getLuminance = (r, g, b) => {
const [rs, gs, bs] = [r, g, b].map(c => {
c /= 255;
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
});
return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
};
const getContrastRatio = (color1, color2) => {
const rgb1 = hex2rgb(color1);
const rgb2 = hex2rgb(color2);
const l1 = getLuminance(...rgb1);
const l2 = getLuminance(...rgb2);
const lighter = Math.max(l1, l2);
const darker = Math.min(l1, l2);
return (lighter + 0.05) / (darker + 0.05);
};
const getTextColor = (bgColor) => {
const contrastWhite = getContrastRatio(bgColor, '#ffffff');
const contrastBlack = getContrastRatio(bgColor, '#000000');
return contrastWhite > contrastBlack ? '#ffffff' : '#000000';
};
console.log(getContrastRatio('#ffffff', '#000000'));
console.log(getTextColor('#ff0000'));
console.log(getTextColor('#ffff00'));
实际应用场景 #
1. 主题色生成 #
javascript
const generateColorPalette = (baseColor) => {
const palette = {};
const rgb = hex2rgb(baseColor);
const [h, s, l] = rgb2hsl(...rgb);
palette[50] = rgb2hex(hsl2rgb(h, s, 95));
palette[100] = rgb2hex(hsl2rgb(h, s, 90));
palette[200] = rgb2hex(hsl2rgb(h, s, 75));
palette[300] = rgb2hex(hsl2rgb(h, s, 60));
palette[400] = rgb2hex(hsl2rgb(h, s, 45));
palette[500] = baseColor;
palette[600] = rgb2hex(hsl2rgb(h, s, 35));
palette[700] = rgb2hex(hsl2rgb(h, s, 25));
palette[800] = rgb2hex(hsl2rgb(h, s, 15));
palette[900] = rgb2hex(hsl2rgb(h, s, 10));
return palette;
};
const palette = generateColorPalette('#3b82f6');
console.log(palette);
2. 颜色选择器 #
javascript
class ColorPicker {
constructor(options = {}) {
this.onChange = options.onChange || (() => {});
this.color = options.defaultColor || '#000000';
}
setColor(hex) {
this.color = hex;
this.onChange({
hex,
rgb: hex2rgb(hex),
hsl: rgb2hsl(...hex2rgb(hex))
});
}
setRgb(r, g, b) {
this.color = rgb2hex([r, g, b]);
this.onChange({
hex: this.color,
rgb: [r, g, b],
hsl: rgb2hsl(r, g, b)
});
}
getColor() {
return {
hex: this.color,
rgb: hex2rgb(this.color),
hsl: rgb2hsl(...hex2rgb(this.color))
};
}
}
const picker = new ColorPicker({
defaultColor: '#ff0000',
onChange: (color) => console.log('颜色变化:', color)
});
3. 图片主色调提取 #
javascript
const extractDominantColor = (imageElement) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = imageElement.width;
canvas.height = imageElement.height;
ctx.drawImage(imageElement, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
let r = 0, g = 0, b = 0, count = 0;
for (let i = 0; i < data.length; i += 4) {
r += data[i];
g += data[i + 1];
b += data[i + 2];
count++;
}
r = Math.round(r / count);
g = Math.round(g / count);
b = Math.round(b / count);
return rgb2hex([r, g, b]);
};
下一步 #
现在你已经掌握了颜色转换,接下来学习 主题管理,了解深色/浅色主题切换的实现!
最后更新:2026-04-04