You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
3.9 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* 将RGBA颜色值转换为HEX格式支持透明度
* @param {string} rgbaStr - RGBA颜色字符串如 "rgba(255, 0, 0, 0.5)"
* @returns {string} HEX颜色字符串如 "#ff000080"
*/
function rgbaToHex(rgbaStr) {
// 验证输入格式
if (!rgbaStr || typeof rgbaStr !== 'string') {
return '';
}
// 首先检查是否已经是HEX格式
if (isHexColor(rgbaStr)) {
return rgbaStr;
}
// 提取RGBA值
const rgbaMatch = rgbaStr.match(/^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*([\d.]+))?\s*\)$/i);
if (!rgbaMatch) {
throw new Error('无效的颜色格式请使用RGBA或HEX格式');
}
// 解析RGBA值
let r = parseInt(rgbaMatch[1], 10);
let g = parseInt(rgbaMatch[2], 10);
let b = parseInt(rgbaMatch[3], 10);
let a = rgbaMatch[4] ? parseFloat(rgbaMatch[4]) : 1;
// 验证取值范围
if ([r, g, b].some((value) => value < 0 || value > 255)) {
throw new Error('RGB值必须在0-255范围内');
}
if (a < 0 || a > 1) {
throw new Error('透明度值必须在0-1范围内');
}
// 将透明度转换为0-255的整数
const alphaInt = Math.round(a * 255);
// 辅助函数:将十进制转换为两位十六进制
const toHex = (num) => {
const hex = num.toString(16);
return hex.length === 1 ? '0' + hex : hex;
};
// 转换为HEX格式
const hexColor = `#${toHex(r)}${toHex(g)}${toHex(b)}`;
// 如果有透明度且不等于1则添加透明度值
if (a !== 1) {
return hexColor + toHex(alphaInt);
}
return hexColor;
}
/**
* 检查字符串是否为有效的HEX颜色格式
* @param {string} str - 颜色字符串
* @returns {boolean} 是否为HEX格式
*/
function isHexColor(str) {
// 移除可能存在的空格
const cleanStr = str.trim();
// HEX颜色正则表达式支持以下格式
// #rgb, #rgba, #rrggbb, #rrggbbaa
const hexRegex = /^#([0-9A-F]{3,4}|[0-9A-F]{6}|[0-9A-F]{8})$/i;
return hexRegex.test(cleanStr);
}
// 或者将isHexColor作为内部函数如果只需要在当前函数中使用
function rgbaToHexWithValidation(rgbaStr) {
// 验证输入格式
if (!rgbaStr || typeof rgbaStr !== 'string') {
throw new Error('请输入有效的颜色字符串');
}
// 检查是否已经是HEX格式的内部函数
const isHexColor = (str) => {
const cleanStr = str.trim();
const hexRegex = /^#([0-9A-F]{3,4}|[0-9A-F]{6}|[0-9A-F]{8})$/i;
return hexRegex.test(cleanStr);
};
// 首先检查是否已经是HEX格式
if (isHexColor(rgbaStr)) {
return rgbaStr;
}
// 提取RGBA值
const rgbaMatch = rgbaStr.match(/^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*([\d.]+))?\s*\)$/i);
if (!rgbaMatch) {
throw new Error(`无效的颜色格式: "${rgbaStr}"请使用RGBA(如 rgba(255,0,0,0.5)) 或 HEX(如 #ff0000) 格式`);
}
// 解析RGBA值
let r = parseInt(rgbaMatch[1], 10);
let g = parseInt(rgbaMatch[2], 10);
let b = parseInt(rgbaMatch[3], 10);
let a = rgbaMatch[4] ? parseFloat(rgbaMatch[4]) : 1;
// 验证取值范围
if ([r, g, b].some((value) => value < 0 || value > 255)) {
throw new Error('RGB值必须在0-255范围内');
}
if (a < 0 || a > 1) {
throw new Error('透明度值必须在0-1范围内');
}
// 将透明度转换为0-255的整数
const alphaInt = Math.round(a * 255);
// 辅助函数:将十进制转换为两位十六进制
const toHex = (num) => {
const hex = num.toString(16);
return hex.length === 1 ? '0' + hex : hex;
};
// 转换为HEX格式
const hexColor = `#${toHex(r)}${toHex(g)}${toHex(b)}`;
// 如果有透明度且不等于1则添加透明度值
if (a !== 1) {
return hexColor + toHex(alphaInt);
}
return hexColor;
}