在网上找的各种颜色的相互转换函数,参考了elementUI的 color-picker组件
function FindRGB(q1, q2, hue) {
if (hue > 360) hue = hue - 360;
if (hue < 0) hue = hue + 360;
if (hue < 60) return (q1 + (q2 - q1) * hue / 60);
else if (hue < 180) return (q2);
else if (hue < 240) return (q1 + (q2 - q1) * (240 - hue) / 60);
else return (q1);
}
function HSLtoRGB(H, S, L) {
var p1, p2;
var tempRGB = { R: 0, G: 0, B: 0 }
L /= 100;
S /= 100;
if (L <= 0.5) p2 = L * (1 + S);
else p2 = L + S - (L * S);
p1 = 2 * L - p2;
if (S == 0) {
tempRGB.R = L;
tempRGB.G = L;
tempRGB.B = L;
}
else {
tempRGB.R = FindRGB(p1, p2, H + 120);
tempRGB.G = FindRGB(p1, p2, H);
tempRGB.B = FindRGB(p1, p2, H - 120);
}
tempRGB.R *= 255;
tempRGB.G *= 255;
tempRGB.B *= 255;
tempRGB.R = Math.round(tempRGB.R);
tempRGB.G = Math.round(tempRGB.G);
tempRGB.B = Math.round(tempRGB.B);
return tempRGB
}
function RGBtoHSL(r, g, b) {
var Min = 0;
var Max = 0;
const HSL = { H: 0, S: 0, L: 0 }
r = (eval(r) / 51) * .2;
g = (eval(g) / 51) * .2;
b = (eval(b) / 51) * .2;
if (eval(r) >= eval(g))
Max = eval(r);
else
Max = eval(g);
if (eval(b) > eval(Max))
Max = eval(b);
if (eval(r) <= eval(g))
Min = eval(r);
else
Min = eval(g);
if (eval(b) < eval(Min))
Min = eval(b);
HSL.L = (eval(Max) + eval(Min)) / 2;
if (eval(Max) == eval(Min)) {
HSL.S = 0;
HSL.H = 0;
}
else {
if (HSL.L < .5)
HSL.S = (eval(Max) - eval(Min)) / (eval(Max) + eval(Min));
if (HSL.L >= .5)
HSL.S = (eval(Max) - eval(Min)) / (2 - eval(Max) - eval(Min));
if (r == Max)
HSL.H = (eval(g) - eval(b)) / (eval(Max) - eval(Min));
if (g == Max)
HSL.H = 2 + ((eval(b) - eval(r)) / (eval(Max) - eval(Min)));
if (b == Max)
HSL.H = 4 + ((eval(r) - eval(g)) / (eval(Max) - eval(Min)));
}
HSL.H = Math.round(HSL.H * 60);
if (HSL.H < 0) HSL.H += 360;
if (HSL.H >= 360) HSL.H -= 360;
HSL.S = Math.round(HSL.S * 100);
HSL.L = Math.round(HSL.L * 100);
return HSL
}
//计算辅助色
function getSecColor(r, g, b) {
const { H, S, L } = RGBtoHSL(r, g, g)
if (H > 120 && H < 290) {//cold
if (Math.abs(210 - (H + 30)) < Math.abs(210 - (H - 30))) {
return HSLtoRGB(H + 30, S, L)
} else {
return HSLtoRGB(H + 30, S, L)
}
} else {
if (Math.abs(30 - (H + 30)) < Math.abs(30 - (H - 30))) {
return HSLtoRGB(H + 30, S, L)
} else {
return HSLtoRGB(H + 30, S, L)
}
}
}
function getContrastColor(r, g, b) {
const hsl = RGBtoHSL(r, g, b)
hsl.H = (hsl.H + 180) % 360
return HSLtoRGB(hsl.H, hsl.S, hsl.L)
}
function getLightenColor(r, g, b) {
const { H, S, L } = RGBtoHSL(r, g, b)
return HSLtoRGB(H, S, Math.min(100, L + 5))
}
function getDarkcolor(r, g, b) {
const { H, S, L } = RGBtoHSL(r, g, b)
return HSLtoRGB(H, S, Math.max(0, L - 5))
}
function setvar(key, value) {
document.body.style.setProperty(key, value)
}
function rgb2hex(rgb) {
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2).toUpperCase();
}
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
function rgba2hex(r, g, b, a) {
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2).toUpperCase();
}
return "#" + hex(r) + hex(g) + hex(b)+hex(256*a-1);
}
function hsv2hsl(hue, sat, val) {
return [
hue,
(sat * val / ((hue = (2 - sat) * val) < 1 ? hue : 2 - hue)) || 0,
hue / 2
];
};
// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
//
const isOnePointZero = function (n) {
return typeof n === 'string' && n.indexOf('.') !== -1 && parseFloat(n) === 1;
};
const isPercentage = function (n) {
return typeof n === 'string' && n.indexOf('%') !== -1;
};
// Take input from [0, n] and return it as [0, 1]
const bound01 = function (value, max) {
if (isOnePointZero(value)) value = '100%';
const processPercent = isPercentage(value);
value = Math.min(max, Math.max(0, parseFloat(value)));
// Automatically convert percentage into number
if (processPercent) {
value = parseInt(value * max, 10) / 100;
}
// Handle floating point rounding errors
if ((Math.abs(value - max) < 0.000001)) {
return 1;
}
// Convert into [0, 1] range if it isn't already
return (value % max) / parseFloat(max);
};
const INT_HEX_MAP = { 10: 'A', 11: 'B', 12: 'C', 13: 'D', 14: 'E', 15: 'F' };
const toHex = function ({ r, g, b }) {
const hexOne = function (value) {
value = Math.min(Math.round(value), 255);
const high = Math.floor(value / 16);
const low = value % 16;
return '' + (INT_HEX_MAP[high] || high) + (INT_HEX_MAP[low] || low);
};
if (isNaN(r) || isNaN(g) || isNaN(b)) return '';
return '#' + hexOne(r) + hexOne(g) + hexOne(b);
};
const HEX_INT_MAP = { A: 10, B: 11, C: 12, D: 13, E: 14, F: 15 };
const parseHexChannel = function (hex) {
if (hex.length === 2) {
return (HEX_INT_MAP[hex[0].toUpperCase()] || +hex[0]) * 16 + (HEX_INT_MAP[hex[1].toUpperCase()] || +hex[1]);
}
return HEX_INT_MAP[hex[1].toUpperCase()] || +hex[1];
};
const hsl2hsv = function (hue, sat, light) {
sat = sat / 100;
light = light / 100;
let smin = sat;
const lmin = Math.max(light, 0.01);
let sv;
let v;
light *= 2;
sat *= (light <= 1) ? light : 2 - light;
smin *= lmin <= 1 ? lmin : 2 - lmin;
v = (light + sat) / 2;
sv = light === 0 ? (2 * smin) / (lmin + smin) : (2 * sat) / (light + sat);
return {
h: hue,
s: sv * 100,
v: v * 100
};
};
// `rgbToHsv`
// Converts an RGB color value to HSV
// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
// *Returns:* { h, s, v } in [0,1]
const rgb2hsv = function (r, g, b) {
r = bound01(r, 255);
g = bound01(g, 255);
b = bound01(b, 255);
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h, s;
let v = max;
const d = max - min;
s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0; // achromatic
} 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: h * 360, s: s * 100, v: v * 100 };
};
// `hsvToRgb`
// Converts an HSV color value to RGB.
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
// *Returns:* { r, g, b } in the set [0, 255]
const hsv2rgb = function (h, s, v) {
h = bound01(h, 360) * 6;
s = bound01(s, 100);
v = bound01(v, 100);
const i = Math.floor(h);
const f = h - i;
const p = v * (1 - s);
const q = v * (1 - f * s);
const t = v * (1 - (1 - f) * s);
const mod = i % 6;
const r = [v, q, p, p, t, v][mod];
const g = [t, v, v, q, p, p][mod];
const b = [p, p, t, v, v, q][mod];
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
};
export default {
FindRGB,
HSLtoRGB,
RGBtoHSL,
getSecColor,
getContrastColor,
getLightenColor,
getDarkcolor,
setvar,
rgb2hex,
hsv2hsl,
toHex,
parseHexChannel,
hsl2hsv,
rgb2hsv,
hsv2rgb,
rgba2hex
}
组件的实现 w-theme.vue
{{ hex }}
COPY
{{ hsla }}
COPY
使用方法。
import wTheme from './components/w-theme.vue';