所有分类
  • 所有分类
  • Html5资源
  • React资源
  • Vue资源
  • Php资源
  • ‌小程序资源
  • Python资源

React 各颜色转换方法、颜色值换算工具HEX、RGB/RGBA、HSL/HSLA、HSV、CMYK

📖 项目简介

基于 React + Tailwind CSS 构建的专业颜色转换工具,支持多种颜色格式的实时转换。无论是设计师、开发者,都能在这个工具中找到所需的颜色转换功能。

✨ 核心功能

🎯 多格式颜色转换

  • HEX 格式: 支持 3 位缩写 (#000, #fff) 和 6 位完整格式 (#ff6b6b)
  • RGB/RGBA: 红绿蓝颜色空间,支持透明度
  • HSL/HSLA: 色相饱和度亮度,更直观的颜色表示
  • HSV: 色相饱和度明度,常用于图像处理
  • CMYK: 青品黄黑,印刷行业标准

🌟 亮点

1. 全面的颜色空间支持

// 支持的颜色格式示例
#ff6b6b          // HEX 6位
#f66             // HEX 3位缩写
rgb(255, 107, 107)           // RGB
rgba(255, 107, 107, 0.8)     // RGBA
hsl(0, 100%, 71%)            // HSL
hsla(0, 100%, 71%, 0.8)      // HSLA
hsv(0, 58%, 100%)            // HSV
cmyk(0%, 58%, 58%, 0%)       // CMYK

🎯 使用场景

  • CSS 开发: 快速获取不同格式的颜色值用于样式开发
  • 主题系统: 构建多主题应用时的颜色格式转换
  • 调试工具: 快速验证和转换颜色值

💻 核心代码实现

HEX 到 RGB 转换(支持缩写)

const hexToRgb = (hex) => {
  // 支持 3 位 HEX 缩写,如 #000, #fff
  if (/^#?([a-f\d])([a-f\d])([a-f\d])$/i.test(hex)) {
    const result = /^#?([a-f\d])([a-f\d])([a-f\d])$/i.exec(hex);
    return {
      r: parseInt(result[1] + result[1], 16),
      g: parseInt(result[2] + result[2], 16),
      b: parseInt(result[3] + result[3], 16),
    };
  }

  // 支持 6 位 HEX,如 #000000, #ffffff
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result
    ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16),
      }
    : null;
};

2. RGB 到 HEX 转换

const rgbToHex = (r, g, b) => {
  return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
};

3. RGB 到 HSL 转换

const rgbToHsl = (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);
        break;
      case g:
        h = (b - r) / d + 2;
        break;
      case b:
        h = (r - g) / d + 4;
        break;
    }
    h /= 6;
  }

  return {
    h: Math.round(h * 360),
    s: Math.round(s * 100),
    l: Math.round(l * 100),
  };
};

4. HSL 到 RGB 转换

const hslToRgb = (h, s, l) => {
  h /= 360;
  s /= 100;
  l /= 100;

  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;
  };

  let r, g, b;

  if (s === 0) {
    r = g = b = l;
  } else {
    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 {
    r: Math.round(r * 255),
    g: Math.round(g * 255),
    b: Math.round(b * 255),
  };
};

5. RGB 到 HSV 转换

const rgbToHsv = (r, g, b) => {
  r /= 255;
  g /= 255;
  b /= 255;

  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  const d = max - min;
  let h,
    s,
    v = max;

  s = max === 0 ? 0 : d / max;

  if (max === min) {
    h = 0;
  } else {
    switch (max) {
      case r:
        h = (g - b) / d + (g < b ? 6 : 0);
        break;
      case g:
        h = (b - r) / d + 2;
        break;
      case b:
        h = (r - g) / d + 4;
        break;
    }
    h /= 6;
  }

  return {
    h: Math.round(h * 360),
    s: Math.round(s * 100),
    v: Math.round(v * 100),
  };
};

6. RGB 到 CMYK 转换

const rgbToCmyk = (r, g, b) => {
  r /= 255;
  g /= 255;
  b /= 255;

  const k = 1 - Math.max(r, g, b);
  const c = (1 - r - k) / (1 - k);
  const m = (1 - g - k) / (1 - k);
  const y = (1 - b - k) / (1 - k);

  return {
    c: Math.round(c * 100),
    m: Math.round(m * 100),
    y: Math.round(y * 100),
    k: Math.round(k * 100),
  };
};

完整源码

import { useState, useEffect } from "react";

export default function ColorConversion() {
  const [colorInput, setColorInput] = useState("#ff6b6b");
  const [colorFormats, setColorFormats] = useState({
    hex: "#ff6b6b",
    rgb: { r: 255, g: 107, b: 107 },
    hsl: { h: 0, s: 100, l: 71 },
    hsv: { h: 0, s: 58, v: 100 },
    cmyk: { c: 0, m: 58, y: 58, k: 0 },
    rgba: { r: 255, g: 107, b: 107, a: 1 },
    hsla: { h: 0, s: 100, l: 71, a: 1 },
  });

  // 颜色转换函数
  const hexToRgb = (hex) => {
    // 支持 3 位 HEX 缩写,如 #000, #fff
    if (/^#?([a-f\d])([a-f\d])([a-f\d])$/i.test(hex)) {
      const result = /^#?([a-f\d])([a-f\d])([a-f\d])$/i.exec(hex);
      return {
        r: parseInt(result[1] + result[1], 16),
        g: parseInt(result[2] + result[2], 16),
        b: parseInt(result[3] + result[3], 16),
      };
    }

    // 支持 6 位 HEX,如 #000000, #ffffff
    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result
      ? {
          r: parseInt(result[1], 16),
          g: parseInt(result[2], 16),
          b: parseInt(result[3], 16),
        }
      : null;
  };

  const rgbToHex = (r, g, b) => {
    return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
  };

  const rgbToHsl = (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);
          break;
        case g:
          h = (b - r) / d + 2;
          break;
        case b:
          h = (r - g) / d + 4;
          break;
      }
      h /= 6;
    }

    return {
      h: Math.round(h * 360),
      s: Math.round(s * 100),
      l: Math.round(l * 100),
    };
  };

  const hslToRgb = (h, s, l) => {
    h /= 360;
    s /= 100;
    l /= 100;

    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;
    };

    let r, g, b;

    if (s === 0) {
      r = g = b = l;
    } else {
      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 {
      r: Math.round(r * 255),
      g: Math.round(g * 255),
      b: Math.round(b * 255),
    };
  };

  const rgbToHsv = (r, g, b) => {
    r /= 255;
    g /= 255;
    b /= 255;

    const max = Math.max(r, g, b);
    const min = Math.min(r, g, b);
    const d = max - min;
    let h,
      s,
      v = max;

    s = max === 0 ? 0 : d / max;

    if (max === min) {
      h = 0;
    } else {
      switch (max) {
        case r:
          h = (g - b) / d + (g < b ? 6 : 0);
          break;
        case g:
          h = (b - r) / d + 2;
          break;
        case b:
          h = (r - g) / d + 4;
          break;
      }
      h /= 6;
    }

    return {
      h: Math.round(h * 360),
      s: Math.round(s * 100),
      v: Math.round(v * 100),
    };
  };

  const rgbToCmyk = (r, g, b) => {
    r /= 255;
    g /= 255;
    b /= 255;

    const k = 1 - Math.max(r, g, b);
    const c = (1 - r - k) / (1 - k);
    const m = (1 - g - k) / (1 - k);
    const y = (1 - b - k) / (1 - k);

    return {
      c: Math.round(c * 100),
      m: Math.round(m * 100),
      y: Math.round(y * 100),
      k: Math.round(k * 100),
    };
  };

  // 更新所有颜色格式
  const updateColorFormats = (input) => {
    let rgb;

    // 检测输入格式并转换为RGB
    if (input.startsWith("#")) {
      rgb = hexToRgb(input);
    } else if (input.startsWith("rgb")) {
      const match = input.match(
        /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/
      );
      if (match) {
        rgb = {
          r: parseInt(match[1]),
          g: parseInt(match[2]),
          b: parseInt(match[3]),
        };
      }
    } else if (input.startsWith("hsl")) {
      const match = input.match(
        /hsla?\((\d+),\s*(\d+)%,\s*(\d+)%(?:,\s*([\d.]+))?\)/
      );
      if (match) {
        rgb = hslToRgb(
          parseInt(match[1]),
          parseInt(match[2]),
          parseInt(match[3])
        );
      }
    }

    if (rgb) {
      const hex = rgbToHex(rgb.r, rgb.g, rgb.b);
      const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
      const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
      const cmyk = rgbToCmyk(rgb.r, rgb.g, rgb.b);

      setColorFormats({
        hex,
        rgb,
        hsl,
        hsv,
        cmyk,
        rgba: { ...rgb, a: 1 },
        hsla: { ...hsl, a: 1 },
      });
    }
  };

  useEffect(() => {
    updateColorFormats(colorInput);
  }, [colorInput]);

  const copyToClipboard = (text) => {
    navigator.clipboard.writeText(text);
  };

  const ColorFormatCard = ({ title, format, copyText }) => (
    <div className="bg-white rounded-lg shadow-md p-3 sm:p-4 border border-gray-200">
      <h3 className="text-base sm:text-lg font-semibold text-gray-800 mb-2">
        {title}
      </h3>
      <div className="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-0">
        <code className="text-xs sm:text-sm bg-gray-100 px-2 py-1 rounded flex-1 font-mono break-all">
          {format}
        </code>
        <button
          onClick={() => copyToClipboard(copyText)}
          className="bg-blue-500 hover:bg-blue-600 text-white px-3 py-1 rounded text-xs sm:text-sm transition-colors whitespace-nowrap"
        >
          复制
        </button>
      </div>
    </div>
  );

  return (
    <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 py-8">
      <div className="container mx-auto px-4 max-w-6xl">
        <div className="text-center mb-8">
          <h1 className="text-4xl font-bold text-gray-800 mb-4">
            颜色转换工具
          </h1>
          <p className="text-gray-600 text-lg">支持多种颜色格式的相互转换</p>
        </div>

        {/* 颜色输入区域 */}
        <div className="bg-white rounded-xl shadow-lg p-6 mb-8">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-2">
              输入颜色值
            </label>
            <div className="flex items-center gap-3">
              <input
                type="text"
                value={colorInput}
                onChange={(e) => setColorInput(e.target.value)}
                placeholder="输入 HEX、RGB、HSL 等颜色值"
                className="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
              />
              <div
                className="w-12 h-12 rounded-lg border-2 border-gray-300 shadow-sm flex-shrink-0"
                style={{ backgroundColor: colorFormats.hex }}
              ></div>
            </div>
          </div>
        </div>

        {/* 颜色格式转换结果 */}
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6">
          <ColorFormatCard
            title="HEX 颜色"
            format={colorFormats.hex}
            copyText={colorFormats.hex}
          />

          <ColorFormatCard
            title="RGB 颜色"
            format={`rgb(${colorFormats.rgb.r}, ${colorFormats.rgb.g}, ${colorFormats.rgb.b})`}
            copyText={`rgb(${colorFormats.rgb.r}, ${colorFormats.rgb.g}, ${colorFormats.rgb.b})`}
          />

          <ColorFormatCard
            title="RGBA 颜色"
            format={`rgba(${colorFormats.rgba.r}, ${colorFormats.rgba.g}, ${colorFormats.rgba.b}, ${colorFormats.rgba.a})`}
            copyText={`rgba(${colorFormats.rgba.r}, ${colorFormats.rgba.g}, ${colorFormats.rgba.b}, ${colorFormats.rgba.a})`}
          />

          <ColorFormatCard
            title="HSL 颜色"
            format={`hsl(${colorFormats.hsl.h}, ${colorFormats.hsl.s}%, ${colorFormats.hsl.l}%)`}
            copyText={`hsl(${colorFormats.hsl.h}, ${colorFormats.hsl.s}%, ${colorFormats.hsl.l}%)`}
          />

          <ColorFormatCard
            title="HSLA 颜色"
            format={`hsla(${colorFormats.hsla.h}, ${colorFormats.hsla.s}%, ${colorFormats.hsla.l}%, ${colorFormats.hsla.a})`}
            copyText={`hsla(${colorFormats.hsla.h}, ${colorFormats.hsla.s}%, ${colorFormats.hsla.l}%, ${colorFormats.hsla.a})`}
          />

          <ColorFormatCard
            title="HSV 颜色"
            format={`hsv(${colorFormats.hsv.h}, ${colorFormats.hsv.s}%, ${colorFormats.hsv.v}%)`}
            copyText={`hsv(${colorFormats.hsv.h}, ${colorFormats.hsv.s}%, ${colorFormats.hsv.v}%)`}
          />

          <ColorFormatCard
            title="CMYK 颜色"
            format={`cmyk(${colorFormats.cmyk.c}%, ${colorFormats.cmyk.m}%, ${colorFormats.cmyk.y}%, ${colorFormats.cmyk.k}%)`}
            copyText={`cmyk(${colorFormats.cmyk.c}%, ${colorFormats.cmyk.m}%, ${colorFormats.cmyk.y}%, ${colorFormats.cmyk.k}%)`}
          />
        </div>

        {/* 使用说明 */}
        <div className="mt-8 sm:mt-12 bg-white rounded-xl shadow-lg p-4 sm:p-6">
          <h2 className="text-xl sm:text-2xl font-bold text-gray-800 mb-4">
            使用说明
          </h2>
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-6">
            <div>
              <h3 className="text-lg font-semibold text-gray-700 mb-2">
                支持的输入格式:
              </h3>
              <ul className="space-y-2 text-gray-600">
                <li>• HEX: #ff6b6b 或 #f66</li>
                <li>• HEX 缩写: #000, #fff, #abc</li>
                <li>• RGB: rgb(255, 107, 107)</li>
                <li>• RGBA: rgba(255, 107, 107, 0.8)</li>
                <li>• HSL: hsl(0, 100%, 71%)</li>
                <li>• HSLA: hsla(0, 100%, 71%, 0.8)</li>
              </ul>
            </div>
            <div>
              <h3 className="text-lg font-semibold text-gray-700 mb-2">
                输出格式:
              </h3>
              <ul className="space-y-2 text-gray-600">
                <li>• HEX 十六进制</li>
                <li>• RGB/RGBA 红绿蓝</li>
                <li>• HSL/HSLA 色相饱和度亮度</li>
                <li>• HSV 色相饱和度明度</li>
                <li>• CMYK 青品黄黑</li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
资源下载
下载价格免费
注意:本网站资源属于虚拟产品,不支持退款。请谨慎购买! 购买后资源无法下载,请联系客服QQ:844475003,微信号:th844475003。
原文链接:https://code.ifrontend.net/archives/723,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?