颜色转换 #

颜色格式概述 #

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