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
+10
View File
@@ -0,0 +1,10 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
+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;
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019-present Fabio Spampinato, Andrew Maney
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

Some files were not shown because too many files have changed in this diff Show More