config redirect

This commit is contained in:
Nuno Coração
2023-01-29 22:30:24 +00:00
parent 17557c7d73
commit 5fb4bd8083
9905 changed files with 1258996 additions and 36355 deletions
+27
View File
@@ -0,0 +1,27 @@
import Type from './type';
import type { RGBA, HSLA, CHANNELS } from '../types';
declare class Channels {
color?: string;
changed: boolean;
data: CHANNELS;
type: Type;
constructor(data: RGBA | HSLA | CHANNELS, color?: string);
set(data: RGBA | HSLA | CHANNELS, color?: string): this;
_ensureHSL(): void;
_ensureRGB(): void;
get r(): number;
get g(): number;
get b(): number;
get h(): number;
get s(): number;
get l(): number;
get a(): number;
set r(r: number);
set g(g: number);
set b(b: number);
set h(h: number);
set s(s: number);
set l(l: number);
set a(a: number);
}
export default Channels;
+132
View File
@@ -0,0 +1,132 @@
/* IMPORT */
import _ from '../utils/index.js';
import Type from './type.js';
import { TYPE } from '../constants.js';
/* MAIN */
class Channels {
/* CONSTRUCTOR */
constructor(data, color) {
this.color = color;
this.changed = false;
this.data = data; //TSC
this.type = new Type();
}
/* API */
set(data, color) {
this.color = color;
this.changed = false;
this.data = data; //TSC
this.type.type = TYPE.ALL;
return this;
}
/* HELPERS */
_ensureHSL() {
const data = this.data;
const { h, s, l } = data;
if (h === undefined)
data.h = _.channel.rgb2hsl(data, 'h');
if (s === undefined)
data.s = _.channel.rgb2hsl(data, 's');
if (l === undefined)
data.l = _.channel.rgb2hsl(data, 'l');
}
_ensureRGB() {
const data = this.data;
const { r, g, b } = data;
if (r === undefined)
data.r = _.channel.hsl2rgb(data, 'r');
if (g === undefined)
data.g = _.channel.hsl2rgb(data, 'g');
if (b === undefined)
data.b = _.channel.hsl2rgb(data, 'b');
}
/* GETTERS */
get r() {
const data = this.data;
const r = data.r;
if (!this.type.is(TYPE.HSL) && r !== undefined)
return r;
this._ensureHSL();
return _.channel.hsl2rgb(data, 'r');
}
get g() {
const data = this.data;
const g = data.g;
if (!this.type.is(TYPE.HSL) && g !== undefined)
return g;
this._ensureHSL();
return _.channel.hsl2rgb(data, 'g');
}
get b() {
const data = this.data;
const b = data.b;
if (!this.type.is(TYPE.HSL) && b !== undefined)
return b;
this._ensureHSL();
return _.channel.hsl2rgb(data, 'b');
}
get h() {
const data = this.data;
const h = data.h;
if (!this.type.is(TYPE.RGB) && h !== undefined)
return h;
this._ensureRGB();
return _.channel.rgb2hsl(data, 'h');
}
get s() {
const data = this.data;
const s = data.s;
if (!this.type.is(TYPE.RGB) && s !== undefined)
return s;
this._ensureRGB();
return _.channel.rgb2hsl(data, 's');
}
get l() {
const data = this.data;
const l = data.l;
if (!this.type.is(TYPE.RGB) && l !== undefined)
return l;
this._ensureRGB();
return _.channel.rgb2hsl(data, 'l');
}
get a() {
return this.data.a;
}
/* SETTERS */
set r(r) {
this.type.set(TYPE.RGB);
this.changed = true;
this.data.r = r;
}
set g(g) {
this.type.set(TYPE.RGB);
this.changed = true;
this.data.g = g;
}
set b(b) {
this.type.set(TYPE.RGB);
this.changed = true;
this.data.b = b;
}
set h(h) {
this.type.set(TYPE.HSL);
this.changed = true;
this.data.h = h;
}
set s(s) {
this.type.set(TYPE.HSL);
this.changed = true;
this.data.s = s;
}
set l(l) {
this.type.set(TYPE.HSL);
this.changed = true;
this.data.l = l;
}
set a(a) {
this.changed = true;
this.data.a = a;
}
}
/* EXPORT */
export default Channels;
+3
View File
@@ -0,0 +1,3 @@
import Channels from './';
declare const channels: Channels;
export default channels;
+6
View File
@@ -0,0 +1,6 @@
/* IMPORT */
import Channels from './/index.js';
/* MAIN */
const channels = new Channels({ r: 0, g: 0, b: 0, a: 0 }, 'transparent');
/* EXPORT */
export default channels;
+8
View File
@@ -0,0 +1,8 @@
declare class Type {
type: number;
get(): number;
set(type: number): void;
reset(): void;
is(type: number): boolean;
}
export default Type;
+26
View File
@@ -0,0 +1,26 @@
/* IMPORT */
import { TYPE } from '../constants.js';
/* MAIN */
class Type {
constructor() {
/* VARIABLES */
this.type = TYPE.ALL;
}
/* API */
get() {
return this.type;
}
set(type) {
if (this.type && this.type !== type)
throw new Error('Cannot change both RGB and HSL channels at the same time');
this.type = type;
}
reset() {
this.type = TYPE.ALL;
}
is(type) {
return this.type === type;
}
}
/* EXPORT */
export default Type;
+7
View File
@@ -0,0 +1,7 @@
import type { Channels } from '../types';
declare const Hex: {
re: RegExp;
parse: (color: string) => Channels | void;
stringify: (channels: Channels) => string;
};
export default Hex;
+43
View File
@@ -0,0 +1,43 @@
/* IMPORT */
import _ from '../utils/index.js';
import ChannelsReusable from '../channels/reusable.js';
import { DEC2HEX } from '../constants.js';
/* MAIN */
const Hex = {
/* VARIABLES */
re: /^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,
/* API */
parse: (color) => {
if (color.charCodeAt(0) !== 35)
return; // '#'
const match = color.match(Hex.re);
if (!match)
return;
const hex = match[1];
const dec = parseInt(hex, 16);
const length = hex.length;
const hasAlpha = length % 4 === 0;
const isFullLength = length > 4;
const multiplier = isFullLength ? 1 : 17;
const bits = isFullLength ? 8 : 4;
const bitsOffset = hasAlpha ? 0 : -1;
const mask = isFullLength ? 255 : 15;
return ChannelsReusable.set({
r: ((dec >> (bits * (bitsOffset + 3))) & mask) * multiplier,
g: ((dec >> (bits * (bitsOffset + 2))) & mask) * multiplier,
b: ((dec >> (bits * (bitsOffset + 1))) & mask) * multiplier,
a: hasAlpha ? (dec & mask) * multiplier / 255 : 1
}, color);
},
stringify: (channels) => {
const { r, g, b, a } = channels;
if (a < 1) { // #RRGGBBAA
return `#${DEC2HEX[Math.round(r)]}${DEC2HEX[Math.round(g)]}${DEC2HEX[Math.round(b)]}${DEC2HEX[Math.round(a * 255)]}`;
}
else { // #RRGGBB
return `#${DEC2HEX[Math.round(r)]}${DEC2HEX[Math.round(g)]}${DEC2HEX[Math.round(b)]}`;
}
}
};
/* EXPORT */
export default Hex;
+9
View File
@@ -0,0 +1,9 @@
import type { Channels } from '../types';
declare const HSL: {
re: RegExp;
hueRe: RegExp;
_hue2deg: (hue: string) => number;
parse: (color: string) => Channels | void;
stringify: (channels: Channels) => string;
};
export default HSL;
+49
View File
@@ -0,0 +1,49 @@
/* IMPORT */
import _ from '../utils/index.js';
import ChannelsReusable from '../channels/reusable.js';
/* MAIN */
const HSL = {
/* VARIABLES */
re: /^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,
hueRe: /^(.+?)(deg|grad|rad|turn)$/i,
/* HELPERS */
_hue2deg: (hue) => {
const match = hue.match(HSL.hueRe);
if (match) {
const [, number, unit] = match;
switch (unit) {
case 'grad': return _.channel.clamp.h(parseFloat(number) * .9);
case 'rad': return _.channel.clamp.h(parseFloat(number) * 180 / Math.PI);
case 'turn': return _.channel.clamp.h(parseFloat(number) * 360);
}
}
return _.channel.clamp.h(parseFloat(hue));
},
/* API */
parse: (color) => {
const charCode = color.charCodeAt(0);
if (charCode !== 104 && charCode !== 72)
return; // 'h'/'H'
const match = color.match(HSL.re);
if (!match)
return;
const [, h, s, l, a, isAlphaPercentage] = match;
return ChannelsReusable.set({
h: HSL._hue2deg(h),
s: _.channel.clamp.s(parseFloat(s)),
l: _.channel.clamp.l(parseFloat(l)),
a: a ? _.channel.clamp.a(isAlphaPercentage ? parseFloat(a) / 100 : parseFloat(a)) : 1
}, color);
},
stringify: (channels) => {
const { h, s, l, a } = channels;
if (a < 1) { // HSLA
return `hsla(${_.lang.round(h)}, ${_.lang.round(s)}%, ${_.lang.round(l)}%, ${a})`;
}
else { // HSL
return `hsl(${_.lang.round(h)}, ${_.lang.round(s)}%, ${_.lang.round(l)}%)`;
}
}
};
/* EXPORT */
export default HSL;
+190
View File
@@ -0,0 +1,190 @@
import type { Channels } from '../types';
declare const Color: {
format: {
keyword: {
colors: {
aliceblue: string;
antiquewhite: string;
aqua: string;
aquamarine: string;
azure: string;
beige: string;
bisque: string;
black: string;
blanchedalmond: string;
blue: string;
blueviolet: string;
brown: string;
burlywood: string;
cadetblue: string;
chartreuse: string;
chocolate: string;
coral: string;
cornflowerblue: string;
cornsilk: string;
crimson: string;
cyanaqua: string;
darkblue: string;
darkcyan: string;
darkgoldenrod: string;
darkgray: string;
darkgreen: string;
darkgrey: string;
darkkhaki: string;
darkmagenta: string;
darkolivegreen: string;
darkorange: string;
darkorchid: string;
darkred: string;
darksalmon: string;
darkseagreen: string;
darkslateblue: string;
darkslategray: string;
darkslategrey: string;
darkturquoise: string;
darkviolet: string;
deeppink: string;
deepskyblue: string;
dimgray: string;
dimgrey: string;
dodgerblue: string;
firebrick: string;
floralwhite: string;
forestgreen: string;
fuchsia: string;
gainsboro: string;
ghostwhite: string;
gold: string;
goldenrod: string;
gray: string;
green: string;
greenyellow: string;
grey: string;
honeydew: string;
hotpink: string;
indianred: string;
indigo: string;
ivory: string;
khaki: string;
lavender: string;
lavenderblush: string;
lawngreen: string;
lemonchiffon: string;
lightblue: string;
lightcoral: string;
lightcyan: string;
lightgoldenrodyellow: string;
lightgray: string;
lightgreen: string;
lightgrey: string;
lightpink: string;
lightsalmon: string;
lightseagreen: string;
lightskyblue: string;
lightslategray: string;
lightslategrey: string;
lightsteelblue: string;
lightyellow: string;
lime: string;
limegreen: string;
linen: string;
magenta: string;
maroon: string;
mediumaquamarine: string;
mediumblue: string;
mediumorchid: string;
mediumpurple: string;
mediumseagreen: string;
mediumslateblue: string;
mediumspringgreen: string;
mediumturquoise: string;
mediumvioletred: string;
midnightblue: string;
mintcream: string;
mistyrose: string;
moccasin: string;
navajowhite: string;
navy: string;
oldlace: string;
olive: string;
olivedrab: string;
orange: string;
orangered: string;
orchid: string;
palegoldenrod: string;
palegreen: string;
paleturquoise: string;
palevioletred: string;
papayawhip: string;
peachpuff: string;
peru: string;
pink: string;
plum: string;
powderblue: string;
purple: string;
rebeccapurple: string;
red: string;
rosybrown: string;
royalblue: string;
saddlebrown: string;
salmon: string;
sandybrown: string;
seagreen: string;
seashell: string;
sienna: string;
silver: string;
skyblue: string;
slateblue: string;
slategray: string;
slategrey: string;
snow: string;
springgreen: string;
tan: string;
teal: string;
thistle: string;
transparent: string;
turquoise: string;
violet: string;
wheat: string;
white: string;
whitesmoke: string;
yellow: string;
yellowgreen: string;
};
parse: (color: string) => void | Channels;
stringify: (channels: Channels) => string | undefined;
};
hex: {
re: RegExp;
parse: (color: string) => void | Channels;
stringify: (channels: Channels) => string;
};
rgb: {
re: RegExp;
parse: (color: string) => void | Channels;
stringify: (channels: Channels) => string;
};
rgba: {
re: RegExp;
parse: (color: string) => void | Channels;
stringify: (channels: Channels) => string;
};
hsl: {
re: RegExp;
hueRe: RegExp;
_hue2deg: (hue: string) => number;
parse: (color: string) => void | Channels;
stringify: (channels: Channels) => string;
};
hsla: {
re: RegExp;
hueRe: RegExp;
_hue2deg: (hue: string) => number;
parse: (color: string) => void | Channels;
stringify: (channels: Channels) => string;
};
};
parse: (color: string | Channels) => Channels;
stringify: (channels: Channels) => string;
};
export default Color;
+44
View File
@@ -0,0 +1,44 @@
/* IMPORT */
import _ from '../utils/index.js';
import Hex from './hex.js';
import HSL from './hsl.js';
import Keyword from './keyword.js';
import RGB from './rgb.js';
import { TYPE } from '../constants.js';
/* MAIN */
const Color = {
/* VARIABLES */
format: {
keyword: Keyword,
hex: Hex,
rgb: RGB,
rgba: RGB,
hsl: HSL,
hsla: HSL
},
/* API */
parse: (color) => {
if (typeof color !== 'string')
return color;
const channels = Hex.parse(color) || RGB.parse(color) || HSL.parse(color) || Keyword.parse(color); // Color providers ordered with performance in mind
if (channels)
return channels;
throw new Error(`Unsupported color format: "${color}"`);
},
stringify: (channels) => {
// SASS returns a keyword if possible, but we avoid doing that as it's slower and doesn't really add any value
if (!channels.changed && channels.color)
return channels.color;
if (channels.type.is(TYPE.HSL) || channels.data.r === undefined) {
return HSL.stringify(channels);
}
else if (channels.a < 1 || !Number.isInteger(channels.r) || !Number.isInteger(channels.g) || !Number.isInteger(channels.b)) {
return RGB.stringify(channels);
}
else {
return Hex.stringify(channels);
}
}
};
/* EXPORT */
export default Color;
+155
View File
@@ -0,0 +1,155 @@
import type { Channels } from '../types';
declare const Keyword: {
colors: {
aliceblue: string;
antiquewhite: string;
aqua: string;
aquamarine: string;
azure: string;
beige: string;
bisque: string;
black: string;
blanchedalmond: string;
blue: string;
blueviolet: string;
brown: string;
burlywood: string;
cadetblue: string;
chartreuse: string;
chocolate: string;
coral: string;
cornflowerblue: string;
cornsilk: string;
crimson: string;
cyanaqua: string;
darkblue: string;
darkcyan: string;
darkgoldenrod: string;
darkgray: string;
darkgreen: string;
darkgrey: string;
darkkhaki: string;
darkmagenta: string;
darkolivegreen: string;
darkorange: string;
darkorchid: string;
darkred: string;
darksalmon: string;
darkseagreen: string;
darkslateblue: string;
darkslategray: string;
darkslategrey: string;
darkturquoise: string;
darkviolet: string;
deeppink: string;
deepskyblue: string;
dimgray: string;
dimgrey: string;
dodgerblue: string;
firebrick: string;
floralwhite: string;
forestgreen: string;
fuchsia: string;
gainsboro: string;
ghostwhite: string;
gold: string;
goldenrod: string;
gray: string;
green: string;
greenyellow: string;
grey: string;
honeydew: string;
hotpink: string;
indianred: string;
indigo: string;
ivory: string;
khaki: string;
lavender: string;
lavenderblush: string;
lawngreen: string;
lemonchiffon: string;
lightblue: string;
lightcoral: string;
lightcyan: string;
lightgoldenrodyellow: string;
lightgray: string;
lightgreen: string;
lightgrey: string;
lightpink: string;
lightsalmon: string;
lightseagreen: string;
lightskyblue: string;
lightslategray: string;
lightslategrey: string;
lightsteelblue: string;
lightyellow: string;
lime: string;
limegreen: string;
linen: string;
magenta: string;
maroon: string;
mediumaquamarine: string;
mediumblue: string;
mediumorchid: string;
mediumpurple: string;
mediumseagreen: string;
mediumslateblue: string;
mediumspringgreen: string;
mediumturquoise: string;
mediumvioletred: string;
midnightblue: string;
mintcream: string;
mistyrose: string;
moccasin: string;
navajowhite: string;
navy: string;
oldlace: string;
olive: string;
olivedrab: string;
orange: string;
orangered: string;
orchid: string;
palegoldenrod: string;
palegreen: string;
paleturquoise: string;
palevioletred: string;
papayawhip: string;
peachpuff: string;
peru: string;
pink: string;
plum: string;
powderblue: string;
purple: string;
rebeccapurple: string;
red: string;
rosybrown: string;
royalblue: string;
saddlebrown: string;
salmon: string;
sandybrown: string;
seagreen: string;
seashell: string;
sienna: string;
silver: string;
skyblue: string;
slateblue: string;
slategray: string;
slategrey: string;
snow: string;
springgreen: string;
tan: string;
teal: string;
thistle: string;
transparent: string;
turquoise: string;
violet: string;
wheat: string;
white: string;
whitesmoke: string;
yellow: string;
yellowgreen: string;
};
parse: (color: string) => Channels | void;
stringify: (channels: Channels) => string | undefined;
};
export default Keyword;
+173
View File
@@ -0,0 +1,173 @@
/* IMPORT */
import Hex from './hex.js';
/* MAIN */
const Keyword = {
/* VARIABLES */
colors: {
aliceblue: '#f0f8ff',
antiquewhite: '#faebd7',
aqua: '#00ffff',
aquamarine: '#7fffd4',
azure: '#f0ffff',
beige: '#f5f5dc',
bisque: '#ffe4c4',
black: '#000000',
blanchedalmond: '#ffebcd',
blue: '#0000ff',
blueviolet: '#8a2be2',
brown: '#a52a2a',
burlywood: '#deb887',
cadetblue: '#5f9ea0',
chartreuse: '#7fff00',
chocolate: '#d2691e',
coral: '#ff7f50',
cornflowerblue: '#6495ed',
cornsilk: '#fff8dc',
crimson: '#dc143c',
cyanaqua: '#00ffff',
darkblue: '#00008b',
darkcyan: '#008b8b',
darkgoldenrod: '#b8860b',
darkgray: '#a9a9a9',
darkgreen: '#006400',
darkgrey: '#a9a9a9',
darkkhaki: '#bdb76b',
darkmagenta: '#8b008b',
darkolivegreen: '#556b2f',
darkorange: '#ff8c00',
darkorchid: '#9932cc',
darkred: '#8b0000',
darksalmon: '#e9967a',
darkseagreen: '#8fbc8f',
darkslateblue: '#483d8b',
darkslategray: '#2f4f4f',
darkslategrey: '#2f4f4f',
darkturquoise: '#00ced1',
darkviolet: '#9400d3',
deeppink: '#ff1493',
deepskyblue: '#00bfff',
dimgray: '#696969',
dimgrey: '#696969',
dodgerblue: '#1e90ff',
firebrick: '#b22222',
floralwhite: '#fffaf0',
forestgreen: '#228b22',
fuchsia: '#ff00ff',
gainsboro: '#dcdcdc',
ghostwhite: '#f8f8ff',
gold: '#ffd700',
goldenrod: '#daa520',
gray: '#808080',
green: '#008000',
greenyellow: '#adff2f',
grey: '#808080',
honeydew: '#f0fff0',
hotpink: '#ff69b4',
indianred: '#cd5c5c',
indigo: '#4b0082',
ivory: '#fffff0',
khaki: '#f0e68c',
lavender: '#e6e6fa',
lavenderblush: '#fff0f5',
lawngreen: '#7cfc00',
lemonchiffon: '#fffacd',
lightblue: '#add8e6',
lightcoral: '#f08080',
lightcyan: '#e0ffff',
lightgoldenrodyellow: '#fafad2',
lightgray: '#d3d3d3',
lightgreen: '#90ee90',
lightgrey: '#d3d3d3',
lightpink: '#ffb6c1',
lightsalmon: '#ffa07a',
lightseagreen: '#20b2aa',
lightskyblue: '#87cefa',
lightslategray: '#778899',
lightslategrey: '#778899',
lightsteelblue: '#b0c4de',
lightyellow: '#ffffe0',
lime: '#00ff00',
limegreen: '#32cd32',
linen: '#faf0e6',
magenta: '#ff00ff',
maroon: '#800000',
mediumaquamarine: '#66cdaa',
mediumblue: '#0000cd',
mediumorchid: '#ba55d3',
mediumpurple: '#9370db',
mediumseagreen: '#3cb371',
mediumslateblue: '#7b68ee',
mediumspringgreen: '#00fa9a',
mediumturquoise: '#48d1cc',
mediumvioletred: '#c71585',
midnightblue: '#191970',
mintcream: '#f5fffa',
mistyrose: '#ffe4e1',
moccasin: '#ffe4b5',
navajowhite: '#ffdead',
navy: '#000080',
oldlace: '#fdf5e6',
olive: '#808000',
olivedrab: '#6b8e23',
orange: '#ffa500',
orangered: '#ff4500',
orchid: '#da70d6',
palegoldenrod: '#eee8aa',
palegreen: '#98fb98',
paleturquoise: '#afeeee',
palevioletred: '#db7093',
papayawhip: '#ffefd5',
peachpuff: '#ffdab9',
peru: '#cd853f',
pink: '#ffc0cb',
plum: '#dda0dd',
powderblue: '#b0e0e6',
purple: '#800080',
rebeccapurple: '#663399',
red: '#ff0000',
rosybrown: '#bc8f8f',
royalblue: '#4169e1',
saddlebrown: '#8b4513',
salmon: '#fa8072',
sandybrown: '#f4a460',
seagreen: '#2e8b57',
seashell: '#fff5ee',
sienna: '#a0522d',
silver: '#c0c0c0',
skyblue: '#87ceeb',
slateblue: '#6a5acd',
slategray: '#708090',
slategrey: '#708090',
snow: '#fffafa',
springgreen: '#00ff7f',
tan: '#d2b48c',
teal: '#008080',
thistle: '#d8bfd8',
transparent: '#00000000',
turquoise: '#40e0d0',
violet: '#ee82ee',
wheat: '#f5deb3',
white: '#ffffff',
whitesmoke: '#f5f5f5',
yellow: '#ffff00',
yellowgreen: '#9acd32'
},
/* API */
parse: (color) => {
color = color.toLowerCase();
const hex = Keyword.colors[color];
if (!hex)
return;
return Hex.parse(hex);
},
stringify: (channels) => {
const hex = Hex.stringify(channels);
for (const name in Keyword.colors) {
if (Keyword.colors[name] === hex)
return name;
}
return;
}
};
/* EXPORT */
export default Keyword;
+7
View File
@@ -0,0 +1,7 @@
import type { Channels } from '../types';
declare const RGB: {
re: RegExp;
parse: (color: string) => Channels | void;
stringify: (channels: Channels) => string;
};
export default RGB;
+35
View File
@@ -0,0 +1,35 @@
/* IMPORT */
import _ from '../utils/index.js';
import ChannelsReusable from '../channels/reusable.js';
/* MAIN */
const RGB = {
/* VARIABLES */
re: /^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,
/* API */
parse: (color) => {
const charCode = color.charCodeAt(0);
if (charCode !== 114 && charCode !== 82)
return; // 'r'/'R'
const match = color.match(RGB.re);
if (!match)
return;
const [, r, isRedPercentage, g, isGreenPercentage, b, isBluePercentage, a, isAlphaPercentage] = match;
return ChannelsReusable.set({
r: _.channel.clamp.r(isRedPercentage ? parseFloat(r) * 2.55 : parseFloat(r)),
g: _.channel.clamp.g(isGreenPercentage ? parseFloat(g) * 2.55 : parseFloat(g)),
b: _.channel.clamp.b(isBluePercentage ? parseFloat(b) * 2.55 : parseFloat(b)),
a: a ? _.channel.clamp.a(isAlphaPercentage ? parseFloat(a) / 100 : parseFloat(a)) : 1
}, color);
},
stringify: (channels) => {
const { r, g, b, a } = channels;
if (a < 1) { // RGBA
return `rgba(${_.lang.round(r)}, ${_.lang.round(g)}, ${_.lang.round(b)}, ${_.lang.round(a)})`;
}
else { // RGB
return `rgb(${_.lang.round(r)}, ${_.lang.round(g)}, ${_.lang.round(b)})`;
}
}
};
/* EXPORT */
export default RGB;
+7
View File
@@ -0,0 +1,7 @@
declare const DEC2HEX: Record<number, string>;
declare const TYPE: {
readonly ALL: 0;
readonly RGB: 1;
readonly HSL: 2;
};
export { DEC2HEX, TYPE };
+13
View File
@@ -0,0 +1,13 @@
/* IMPORT */
import _ from './utils/index.js';
/* MAIN */
const DEC2HEX = {};
for (let i = 0; i <= 255; i++)
DEC2HEX[i] = _.unit.dec2hex(i); // Populating dynamically, striking a balance between code size and performance
const TYPE = {
ALL: 0,
RGB: 1,
HSL: 2
};
/* EXPORT */
export { DEC2HEX, TYPE };
+1
View File
@@ -0,0 +1 @@
export * from './methods';
+2
View File
@@ -0,0 +1,2 @@
/* EXPORT */
export * from './methods/index.js';
+3
View File
@@ -0,0 +1,3 @@
import type { CHANNELS, Channels } from '../types';
declare const adjust: (color: string | Channels, channels: Partial<CHANNELS>) => string;
export default adjust;
+16
View File
@@ -0,0 +1,16 @@
/* IMPORT */
import Color from '../color/index.js';
import change from './change.js';
/* MAIN */
const adjust = (color, channels) => {
const ch = Color.parse(color);
const changes = {};
for (const c in channels) {
if (!channels[c])
continue;
changes[c] = ch[c] + channels[c];
}
return change(color, changes);
};
/* EXPORT */
export default adjust;
+3
View File
@@ -0,0 +1,3 @@
import type { CHANNEL, Channels } from '../types';
declare const adjustChannel: (color: string | Channels, channel: CHANNEL, amount: number) => string;
export default adjustChannel;
+14
View File
@@ -0,0 +1,14 @@
/* IMPORT */
import _ from '../utils/index.js';
import Color from '../color/index.js';
/* MAIN */
const adjustChannel = (color, channel, amount) => {
const channels = Color.parse(color);
const amountCurrent = channels[channel];
const amountNext = _.channel.clamp[channel](amountCurrent + amount);
if (amountCurrent !== amountNext)
channels[channel] = amountNext;
return Color.stringify(channels);
};
/* EXPORT */
export default adjustChannel;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const alpha: (color: string | Channels) => number;
export default alpha;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import channel from './channel.js';
/* MAIN */
const alpha = (color) => {
return channel(color, 'a');
};
/* EXPORT */
export default alpha;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const blue: (color: string | Channels) => number;
export default blue;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import channel from './channel.js';
/* MAIN */
const blue = (color) => {
return channel(color, 'b');
};
/* EXPORT */
export default blue;
+3
View File
@@ -0,0 +1,3 @@
import type { CHANNELS, Channels } from '../types';
declare const change: (color: string | Channels, channels: Partial<CHANNELS>) => string;
export default change;
+13
View File
@@ -0,0 +1,13 @@
/* IMPORT */
import _ from '../utils/index.js';
import Color from '../color/index.js';
/* MAIN */
const change = (color, channels) => {
const ch = Color.parse(color);
for (const c in channels) {
ch[c] = _.channel.clamp[c](channels[c]);
}
return Color.stringify(ch);
};
/* EXPORT */
export default change;
+3
View File
@@ -0,0 +1,3 @@
import type { CHANNEL, Channels } from '../types';
declare const channel: (color: string | Channels, channel: CHANNEL) => number;
export default channel;
+9
View File
@@ -0,0 +1,9 @@
/* IMPORT */
import _ from '../utils/index.js';
import Color from '../color/index.js';
/* MAIN */
const channel = (color, channel) => {
return _.lang.round(Color.parse(color)[channel]);
};
/* EXPORT */
export default channel;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const complement: (color: string | Channels) => string;
export default complement;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import adjustChannel from './adjust_channel.js';
/* MAIN */
const complement = (color) => {
return adjustChannel(color, 'h', 180);
};
/* EXPORT */
export default complement;
+2
View File
@@ -0,0 +1,2 @@
declare const contrast: (color1: string, color2: string) => number;
export default contrast;
+14
View File
@@ -0,0 +1,14 @@
/* IMPORT */
import _ from '../utils/index.js';
import luminance from './luminance.js';
/* MAIN */
const contrast = (color1, color2) => {
const luminance1 = luminance(color1);
const luminance2 = luminance(color2);
const max = Math.max(luminance1, luminance2);
const min = Math.min(luminance1, luminance2);
const ratio = (max + Number.EPSILON) / (min + Number.EPSILON);
return _.lang.round(_.lang.clamp(ratio, 1, 10));
};
/* EXPORT */
export default contrast;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const darken: (color: string | Channels, amount: number) => string;
export default darken;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import adjustChannel from './adjust_channel.js';
/* MAIN */
const darken = (color, amount) => {
return adjustChannel(color, 'l', -amount);
};
/* EXPORT */
export default darken;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const desaturate: (color: string | Channels, amount: number) => string;
export default desaturate;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import adjustChannel from './adjust_channel.js';
/* MAIN */
const desaturate = (color, amount) => {
return adjustChannel(color, 's', -amount);
};
/* EXPORT */
export default desaturate;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const grayscale: (color: string | Channels) => string;
export default grayscale;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import change from './change.js';
/* MAIN */
const grayscale = (color) => {
return change(color, { s: 0 });
};
/* EXPORT */
export default grayscale;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const green: (color: string | Channels) => number;
export default green;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import channel from './channel.js';
/* MAIN */
const green = (color) => {
return channel(color, 'g');
};
/* EXPORT */
export default green;
+2
View File
@@ -0,0 +1,2 @@
declare const hsla: (h: number, s: number, l: number, a?: number) => string;
export default hsla;
+16
View File
@@ -0,0 +1,16 @@
/* IMPORT */
import _ from '../utils/index.js';
import ChannelsReusable from '../channels/reusable.js';
import Color from '../color/index.js';
/* MAIN */
const hsla = (h, s, l, a = 1) => {
const channels = ChannelsReusable.set({
h: _.channel.clamp.h(h),
s: _.channel.clamp.s(s),
l: _.channel.clamp.l(l),
a: _.channel.clamp.a(a)
});
return Color.stringify(channels);
};
/* EXPORT */
export default hsla;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const hue: (color: string | Channels) => number;
export default hue;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import channel from './channel.js';
/* MAIN */
const hue = (color) => {
return channel(color, 'h');
};
/* EXPORT */
export default hue;
+39
View File
@@ -0,0 +1,39 @@
import hex from './rgba';
import rgb from './rgba';
import rgba from './rgba';
import hsl from './hsla';
import hsla from './hsla';
import toKeyword from './to_keyword';
import toHex from './to_hex';
import toRgba from './to_rgba';
import toHsla from './to_hsla';
import channel from './channel';
import red from './red';
import green from './green';
import blue from './blue';
import hue from './hue';
import saturation from './saturation';
import lightness from './lightness';
import alpha from './alpha';
import opacity from './alpha';
import contrast from './contrast';
import luminance from './luminance';
import isDark from './is_dark';
import isLight from './is_light';
import isValid from './is_valid';
import saturate from './saturate';
import desaturate from './desaturate';
import lighten from './lighten';
import darken from './darken';
import opacify from './opacify';
import fadeIn from './opacify';
import transparentize from './transparentize';
import fadeOut from './transparentize';
import complement from './complement';
import grayscale from './grayscale';
import adjust from './adjust';
import change from './change';
import invert from './invert';
import mix from './mix';
import scale from './scale';
export { hex, rgb, rgba, hsl, hsla, toKeyword, toHex, toRgba, toHsla, channel, red, green, blue, hue, saturation, lightness, alpha, opacity, contrast, luminance, isDark, isLight, isValid, saturate, desaturate, lighten, darken, opacify, fadeIn, transparentize, fadeOut, complement, grayscale, adjust, change, invert, mix, scale };
+53
View File
@@ -0,0 +1,53 @@
/* IMPORT */
import hex from './rgba.js'; // Alias
import rgb from './rgba.js'; // Alias
import rgba from './rgba.js';
import hsl from './hsla.js'; // Alias
import hsla from './hsla.js';
import toKeyword from './to_keyword.js';
import toHex from './to_hex.js';
import toRgba from './to_rgba.js';
import toHsla from './to_hsla.js';
import channel from './channel.js';
import red from './red.js';
import green from './green.js';
import blue from './blue.js';
import hue from './hue.js';
import saturation from './saturation.js';
import lightness from './lightness.js';
import alpha from './alpha.js';
import opacity from './alpha.js'; // Alias
import contrast from './contrast.js';
import luminance from './luminance.js';
import isDark from './is_dark.js';
import isLight from './is_light.js';
import isValid from './is_valid.js';
import saturate from './saturate.js';
import desaturate from './desaturate.js';
import lighten from './lighten.js';
import darken from './darken.js';
import opacify from './opacify.js';
import fadeIn from './opacify.js'; // Alias
import transparentize from './transparentize.js';
import fadeOut from './transparentize.js'; // Alias
import complement from './complement.js';
import grayscale from './grayscale.js';
import adjust from './adjust.js';
import change from './change.js';
import invert from './invert.js';
import mix from './mix.js';
import scale from './scale.js';
/* EXPORT */
export {
/* CREATE */
hex, rgb, rgba, hsl, hsla,
/* CONVERT */
toKeyword, toHex, toRgba, toHsla,
/* GET - CHANNEL */
channel, red, green, blue, hue, saturation, lightness, alpha, opacity,
/* GET - MORE */
contrast, luminance, isDark, isLight, isValid,
/* EDIT - CHANNEL */
saturate, desaturate, lighten, darken, opacify, fadeIn, transparentize, fadeOut, complement, grayscale,
/* EDIT - MORE */
adjust, change, invert, mix, scale };
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const invert: (color: string | Channels, weight?: number) => string;
export default invert;
+13
View File
@@ -0,0 +1,13 @@
/* IMPORT */
import Color from '../color/index.js';
import mix from './mix.js';
/* MAIN */
const invert = (color, weight = 100) => {
const inverse = Color.parse(color);
inverse.r = 255 - inverse.r;
inverse.g = 255 - inverse.g;
inverse.b = 255 - inverse.b;
return mix(inverse, color, weight);
};
/* EXPORT */
export default invert;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const isDark: (color: string | Channels) => boolean;
export default isDark;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import isLight from './is_light.js';
/* MAIN */
const isDark = (color) => {
return !isLight(color);
};
/* EXPORT */
export default isDark;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const isLight: (color: string | Channels) => boolean;
export default isLight;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import luminance from './luminance.js';
/* MAIN */
const isLight = (color) => {
return luminance(color) >= .5;
};
/* EXPORT */
export default isLight;
+2
View File
@@ -0,0 +1,2 @@
declare const isValid: (color: string) => boolean;
export default isValid;
+14
View File
@@ -0,0 +1,14 @@
/* IMPORT */
import Color from '../color/index.js';
/* MAIN */
const isValid = (color) => {
try {
Color.parse(color);
return true;
}
catch {
return false;
}
};
/* EXPORT */
export default isValid;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const lighten: (color: string | Channels, amount: number) => string;
export default lighten;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import adjustChannel from './adjust_channel.js';
/* MAIN */
const lighten = (color, amount) => {
return adjustChannel(color, 'l', amount);
};
/* EXPORT */
export default lighten;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const lightness: (color: string | Channels) => number;
export default lightness;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import channel from './channel.js';
/* MAIN */
const lightness = (color) => {
return channel(color, 'l');
};
/* EXPORT */
export default lightness;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const luminance: (color: string | Channels) => number;
export default luminance;
+12
View File
@@ -0,0 +1,12 @@
/* IMPORT */
import _ from '../utils/index.js';
import Color from '../color/index.js';
/* MAIN */
//SOURCE: https://planetcalc.com/7779
const luminance = (color) => {
const { r, g, b } = Color.parse(color);
const luminance = .2126 * _.channel.toLinear(r) + .7152 * _.channel.toLinear(g) + .0722 * _.channel.toLinear(b);
return _.lang.round(luminance);
};
/* EXPORT */
export default luminance;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const mix: (color1: string | Channels, color2: string | Channels, weight?: number) => string;
export default mix;
+22
View File
@@ -0,0 +1,22 @@
/* IMPORT */
import Color from '../color/index.js';
import rgba from './rgba.js';
/* MAIN */
//SOURCE: https://github.com/sass/dart-sass/blob/7457d2e9e7e623d9844ffd037a070cf32d39c348/lib/src/functions/color.dart#L718-L756
const mix = (color1, color2, weight = 50) => {
const { r: r1, g: g1, b: b1, a: a1 } = Color.parse(color1);
const { r: r2, g: g2, b: b2, a: a2 } = Color.parse(color2);
const weightScale = weight / 100;
const weightNormalized = (weightScale * 2) - 1;
const alphaDelta = a1 - a2;
const weight1combined = ((weightNormalized * alphaDelta) === -1) ? weightNormalized : (weightNormalized + alphaDelta) / (1 + weightNormalized * alphaDelta);
const weight1 = (weight1combined + 1) / 2;
const weight2 = 1 - weight1;
const r = (r1 * weight1) + (r2 * weight2);
const g = (g1 * weight1) + (g2 * weight2);
const b = (b1 * weight1) + (b2 * weight2);
const a = (a1 * weightScale) + (a2 * (1 - weightScale));
return rgba(r, g, b, a);
};
/* EXPORT */
export default mix;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const opacify: (color: string | Channels, amount: number) => string;
export default opacify;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import adjustChannel from './adjust_channel.js';
/* MAIN */
const opacify = (color, amount) => {
return adjustChannel(color, 'a', amount);
};
/* EXPORT */
export default opacify;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const red: (color: string | Channels) => number;
export default red;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import channel from './channel.js';
/* MAIN */
const red = (color) => {
return channel(color, 'r');
};
/* EXPORT */
export default red;
+7
View File
@@ -0,0 +1,7 @@
import type { Channels } from '../types';
declare type IRgba = {
(color: string | Channels, opacity: number): string;
(r: number, g: number, b: number, a?: number): string;
};
declare const rgba: IRgba;
export default rgba;
+19
View File
@@ -0,0 +1,19 @@
/* IMPORT */
import _ from '../utils/index.js';
import ChannelsReusable from '../channels/reusable.js';
import Color from '../color/index.js';
import change from './change.js';
/* MAIN */
const rgba = (r, g, b = 0, a = 1) => {
if (typeof r !== 'number')
return change(r, { a: g });
const channels = ChannelsReusable.set({
r: _.channel.clamp.r(r),
g: _.channel.clamp.g(g),
b: _.channel.clamp.b(b),
a: _.channel.clamp.a(a)
});
return Color.stringify(channels);
};
/* EXPORT */
export default rgba;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const saturate: (color: string | Channels, amount: number) => string;
export default saturate;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import adjustChannel from './adjust_channel.js';
/* MAIN */
const saturate = (color, amount) => {
return adjustChannel(color, 's', amount);
};
/* EXPORT */
export default saturate;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const saturation: (color: string | Channels) => number;
export default saturation;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import channel from './channel.js';
/* MAIN */
const saturation = (color) => {
return channel(color, 's');
};
/* EXPORT */
export default saturation;
+3
View File
@@ -0,0 +1,3 @@
import type { CHANNELS, Channels } from '../types';
declare const scale: (color: string | Channels, channels: Partial<CHANNELS>) => string;
export default scale;
+16
View File
@@ -0,0 +1,16 @@
/* IMPORT */
import _ from '../utils/index.js';
import Color from '../color/index.js';
import adjust from './adjust.js';
/* MAIN */
const scale = (color, channels) => {
const ch = Color.parse(color);
const adjustments = {};
const delta = (amount, weight, max) => weight > 0 ? (max - amount) * weight / 100 : amount * weight / 100;
for (const c in channels) {
adjustments[c] = delta(ch[c], channels[c], _.channel.max[c]);
}
return adjust(color, adjustments);
};
/* EXPORT */
export default scale;
+2
View File
@@ -0,0 +1,2 @@
declare const toHex: (color: string) => string;
export default toHex;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import Color from '../color/index.js';
/* MAIN */
const toHex = (color) => {
return Color.format.hex.stringify(Color.parse(color));
};
/* EXPORT */
export default toHex;
+2
View File
@@ -0,0 +1,2 @@
declare const toHsla: (color: string) => string;
export default toHsla;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import Color from '../color/index.js';
/* MAIN */
const toHsla = (color) => {
return Color.format.hsla.stringify(Color.parse(color));
};
/* EXPORT */
export default toHsla;
+2
View File
@@ -0,0 +1,2 @@
declare const toKeyword: (color: string) => string | undefined;
export default toKeyword;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import Color from '../color/index.js';
/* MAIN */
const toKeyword = (color) => {
return Color.format.keyword.stringify(Color.parse(color));
};
/* EXPORT */
export default toKeyword;
+2
View File
@@ -0,0 +1,2 @@
declare const toRgba: (color: string) => string;
export default toRgba;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import Color from '../color/index.js';
/* MAIN */
const toRgba = (color) => {
return Color.format.rgba.stringify(Color.parse(color));
};
/* EXPORT */
export default toRgba;
+3
View File
@@ -0,0 +1,3 @@
import type { Channels } from '../types';
declare const transparentize: (color: string | Channels, amount: number) => string;
export default transparentize;
+8
View File
@@ -0,0 +1,8 @@
/* IMPORT */
import adjustChannel from './adjust_channel.js';
/* MAIN */
const transparentize = (color, amount) => {
return adjustChannel(color, 'a', -amount);
};
/* EXPORT */
export default transparentize;
+20
View File
@@ -0,0 +1,20 @@
import type Channels from './channels';
declare type ALPHA = {
a: number;
};
declare type RGB = {
r: number;
g: number;
b: number;
};
declare type RGBA = RGB & ALPHA;
declare type HSL = {
h: number;
s: number;
l: number;
};
declare type HSLA = HSL & ALPHA;
declare type CHANNEL = 'r' | 'g' | 'b' | 'h' | 's' | 'l' | 'a';
declare type CHANNELS = Record<CHANNEL, number>;
export type { Channels };
export type { ALPHA, RGB, RGBA, HSL, HSLA, CHANNEL, CHANNELS };
+2
View File
@@ -0,0 +1,2 @@
/* IMPORT */
export {};
+34
View File
@@ -0,0 +1,34 @@
import type { RGB, HSL } from '../types';
declare const Channel: {
min: {
r: number;
g: number;
b: number;
s: number;
l: number;
a: number;
};
max: {
r: number;
g: number;
b: number;
h: number;
s: number;
l: number;
a: number;
};
clamp: {
r: (r: number) => number;
g: (g: number) => number;
b: (b: number) => number;
h: (h: number) => number;
s: (s: number) => number;
l: (l: number) => number;
a: (a: number) => number;
};
toLinear: (c: number) => number;
hue2rgb: (p: number, q: number, t: number) => number;
hsl2rgb: ({ h, s, l }: HSL, channel: keyof RGB) => number;
rgb2hsl: ({ r, g, b }: RGB, channel: keyof HSL) => number;
};
export default Channel;
+89
View File
@@ -0,0 +1,89 @@
/* IMPORT */
/* MAIN */
const Channel = {
/* CLAMP */
min: {
r: 0,
g: 0,
b: 0,
s: 0,
l: 0,
a: 0
},
max: {
r: 255,
g: 255,
b: 255,
h: 360,
s: 100,
l: 100,
a: 1
},
clamp: {
r: (r) => r >= 255 ? 255 : (r < 0 ? 0 : r),
g: (g) => g >= 255 ? 255 : (g < 0 ? 0 : g),
b: (b) => b >= 255 ? 255 : (b < 0 ? 0 : b),
h: (h) => h % 360,
s: (s) => s >= 100 ? 100 : (s < 0 ? 0 : s),
l: (l) => l >= 100 ? 100 : (l < 0 ? 0 : l),
a: (a) => a >= 1 ? 1 : (a < 0 ? 0 : a)
},
/* CONVERSION */
//SOURCE: https://planetcalc.com/7779
toLinear: (c) => {
const n = c / 255;
return c > .03928 ? Math.pow(((n + .055) / 1.055), 2.4) : n / 12.92;
},
//SOURCE: https://gist.github.com/mjackson/5311256
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;
},
hsl2rgb: ({ h, s, l }, channel) => {
if (!s)
return l * 2.55; // Achromatic
h /= 360;
s /= 100;
l /= 100;
const q = (l < .5) ? l * (1 + s) : (l + s) - (l * s);
const p = 2 * l - q;
switch (channel) {
case 'r': return Channel.hue2rgb(p, q, h + 1 / 3) * 255;
case 'g': return Channel.hue2rgb(p, q, h) * 255;
case 'b': return Channel.hue2rgb(p, q, h - 1 / 3) * 255;
}
},
rgb2hsl: ({ r, g, b }, channel) => {
r /= 255;
g /= 255;
b /= 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const l = (max + min) / 2;
if (channel === 'l')
return l * 100;
if (max === min)
return 0; // Achromatic
const d = max - min;
const s = (l > .5) ? d / (2 - max - min) : d / (max + min);
if (channel === 's')
return s * 100;
switch (max) {
case r: return ((g - b) / d + (g < b ? 6 : 0)) * 60;
case g: return ((b - r) / d + 2) * 60;
case b: return ((r - g) / d + 4) * 60;
default: return -1; //TSC: TypeScript is stupid and complains if there isn't this useless default statement
}
}
};
/* EXPORT */
export default Channel;
+42
View File
@@ -0,0 +1,42 @@
declare const Utils: {
channel: {
min: {
r: number;
g: number;
b: number;
s: number;
l: number;
a: number;
};
max: {
r: number;
g: number;
b: number;
h: number;
s: number;
l: number;
a: number;
};
clamp: {
r: (r: number) => number;
g: (g: number) => number;
b: (b: number) => number;
h: (h: number) => number;
s: (s: number) => number;
l: (l: number) => number;
a: (a: number) => number;
};
toLinear: (c: number) => number;
hue2rgb: (p: number, q: number, t: number) => number;
hsl2rgb: ({ h, s, l }: import("../types").HSL, channel: keyof import("../types").RGB) => number;
rgb2hsl: ({ r, g, b }: import("../types").RGB, channel: keyof import("../types").HSL) => number;
};
lang: {
clamp: (number: number, lower: number, upper: number) => number;
round: (number: number) => number;
};
unit: {
dec2hex: (dec: number) => string;
};
};
export default Utils;
+12
View File
@@ -0,0 +1,12 @@
/* IMPORT */
import channel from './channel.js';
import lang from './lang.js';
import unit from './unit.js';
/* MAIN */
const Utils = {
channel,
lang,
unit
};
/* EXPORT */
export default Utils;
+5
View File
@@ -0,0 +1,5 @@
declare const Lang: {
clamp: (number: number, lower: number, upper: number) => number;
round: (number: number) => number;
};
export default Lang;
+14
View File
@@ -0,0 +1,14 @@
/* MAIN */
const Lang = {
/* API */
clamp: (number, lower, upper) => {
if (lower > upper)
return Math.min(lower, Math.max(upper, number));
return Math.min(upper, Math.max(lower, number));
},
round: (number) => {
return Math.round(number * 10000000000) / 10000000000;
}
};
/* EXPORT */
export default Lang;
+4
View File
@@ -0,0 +1,4 @@
declare const Unit: {
dec2hex: (dec: number) => string;
};
export default Unit;
+10
View File
@@ -0,0 +1,10 @@
/* MAIN */
const Unit = {
/* API */
dec2hex: (dec) => {
const hex = Math.round(dec).toString(16);
return hex.length > 1 ? hex : `0${hex}`;
}
};
/* EXPORT */
export default Unit;