@exabytellc/utils
Version:
EB react utils to make everything a little easier!
487 lines (444 loc) • 18.5 kB
JavaScript
import { handleTryCatch } from "../_helpers/handleError";
import { clamp, randomInt, randomIntSeed } from "../math";
import { isArr, isNum, isStr } from "../types";
import Color from "../Color";
// colors
export const Colors = {
get transparent() { return new Color(0, 0, 0, 0) },
get light() { return new Color(238, 238, 238) },
get dark() { return new Color(51, 51, 51) },
get error() { return new Color(220, 53, 69) },
get danger() { return new Color(220, 53, 69) },
get warning() { return new Color(255, 193, 7) },
get warn() { return new Color(255, 193, 7) },
get success() { return new Color(40, 167, 69) },
get info() { return new Color(23, 162, 184) },
get link() { return new Color(138, 180, 248) },
get linkClicked() { return new Color(197, 138, 249) },
get aliceblue() { return new Color(240, 248, 255) },
get antiquewhite() { return new Color(250, 235, 215) },
get aqua() { return new Color(0, 255, 255) },
get aquamarine() { return new Color(127, 255, 212) },
get azure() { return new Color(240, 255, 255) },
get beige() { return new Color(245, 245, 220) },
get bisque() { return new Color(255, 228, 196) },
get black() { return new Color(0, 0, 0) },
get blanchedalmond() { return new Color(255, 235, 205) },
get blue() { return new Color(0, 0, 255) },
get blueviolet() { return new Color(138, 43, 226) },
get brown() { return new Color(165, 42, 42) },
get burlywood() { return new Color(222, 184, 135) },
get cadetblue() { return new Color(95, 158, 160) },
get chartreuse() { return new Color(127, 255, 0) },
get chocolate() { return new Color(210, 105, 30) },
get coral() { return new Color(255, 127, 80) },
get cornflowerblue() { return new Color(100, 149, 237) },
get cornsilk() { return new Color(255, 248, 220) },
get crimson() { return new Color(220, 20, 60) },
get cyan() { return new Color(0, 255, 255) },
get darkblue() { return new Color(0, 0, 139) },
get darkcyan() { return new Color(0, 139, 139) },
get darkgoldenrod() { return new Color(184, 134, 11) },
get darkgray() { return new Color(169, 169, 169) },
get darkgreen() { return new Color(0, 100, 0) },
get darkkhaki() { return new Color(189, 183, 107) },
get darkmagenta() { return new Color(139, 0, 139) },
get darkolivegreen() { return new Color(85, 107, 47) },
get darkorange() { return new Color(255, 140, 0) },
get darkorchid() { return new Color(153, 50, 204) },
get darkred() { return new Color(139, 0, 0) },
get darksalmon() { return new Color(233, 150, 122) },
get darkseagreen() { return new Color(143, 188, 143) },
get darkslateblue() { return new Color(72, 61, 139) },
get darkslategray() { return new Color(47, 79, 79) },
get darkturquoise() { return new Color(0, 206, 209) },
get darkviolet() { return new Color(148, 0, 211) },
get deeppink() { return new Color(255, 20, 147) },
get deepskyblue() { return new Color(0, 191, 255) },
get dimgray() { return new Color(105, 105, 105) },
get dodgerblue() { return new Color(30, 144, 255) },
get firebrick() { return new Color(178, 34, 34) },
get floralwhite() { return new Color(255, 250, 240) },
get forestgreen() { return new Color(34, 139, 34) },
get fuchsia() { return new Color(255, 0, 255) },
get gainsboro() { return new Color(220, 220, 220) },
get ghostwhite() { return new Color(248, 248, 255) },
get gold() { return new Color(255, 215, 0) },
get goldenrod() { return new Color(218, 165, 32) },
get gray() { return new Color(128, 128, 128) },
get green() { return new Color(0, 128, 0) },
get greenyellow() { return new Color(173, 255, 47) },
get honeydew() { return new Color(240, 255, 240) },
get hotpink() { return new Color(255, 105, 180) },
get indianred() { return new Color(205, 92, 92) },
get indigo() { return new Color(75, 0, 130) },
get ivory() { return new Color(255, 255, 240) },
get khaki() { return new Color(240, 230, 140) },
get lavender() { return new Color(230, 230, 250) },
get lavenderblush() { return new Color(255, 240, 245) },
get lawngreen() { return new Color(124, 252, 0) },
get lemonchiffon() { return new Color(255, 250, 205) },
get lightblue() { return new Color(173, 216, 230) },
get lightcoral() { return new Color(240, 128, 128) },
get lightcyan() { return new Color(224, 255, 255) },
get lightgoldenrodyellow() { return new Color(250, 250, 210) },
get lightgrey() { return new Color(211, 211, 211) },
get lightgreen() { return new Color(144, 238, 144) },
get lightpink() { return new Color(255, 182, 193) },
get lightsalmon() { return new Color(255, 160, 122) },
get lightseagreen() { return new Color(32, 178, 170) },
get lightskyblue() { return new Color(135, 206, 250) },
get lightslategray() { return new Color(119, 136, 153) },
get lightsteelblue() { return new Color(176, 196, 222) },
get lightyellow() { return new Color(255, 255, 224) },
get lime() { return new Color(0, 255, 0) },
get limegreen() { return new Color(50, 205, 50) },
get linen() { return new Color(250, 240, 230) },
get magenta() { return new Color(255, 0, 255) },
get maroon() { return new Color(128, 0, 0) },
get mediumaquamarine() { return new Color(102, 205, 170) },
get mediumblue() { return new Color(0, 0, 205) },
get mediumorchid() { return new Color(186, 85, 211) },
get mediumpurple() { return new Color(147, 112, 216) },
get mediumseagreen() { return new Color(60, 179, 113) },
get mediumslateblue() { return new Color(123, 104, 238) },
get mediumspringgreen() { return new Color(0, 250, 154) },
get mediumturquoise() { return new Color(72, 209, 204) },
get mediumvioletred() { return new Color(199, 21, 133) },
get midnightblue() { return new Color(25, 25, 112) },
get mintcream() { return new Color(245, 255, 250) },
get mistyrose() { return new Color(255, 228, 225) },
get moccasin() { return new Color(255, 228, 181) },
get navajowhite() { return new Color(255, 222, 173) },
get navy() { return new Color(0, 0, 128) },
get oldlace() { return new Color(253, 245, 230) },
get olive() { return new Color(128, 128, 0) },
get olivedrab() { return new Color(107, 142, 35) },
get orange() { return new Color(255, 165, 0) },
get orangered() { return new Color(255, 69, 0) },
get orchid() { return new Color(218, 112, 214) },
get palegoldenrod() { return new Color(238, 232, 170) },
get palegreen() { return new Color(152, 251, 152) },
get paleturquoise() { return new Color(175, 238, 238) },
get palevioletred() { return new Color(216, 112, 147) },
get papayawhip() { return new Color(255, 239, 213) },
get peachpuff() { return new Color(255, 218, 185) },
get peru() { return new Color(205, 133, 63) },
get pink() { return new Color(255, 192, 203) },
get plum() { return new Color(221, 160, 221) },
get powderblue() { return new Color(176, 224, 230) },
get purple() { return new Color(128, 0, 128) },
get rebeccapurple() { return new Color(102, 51, 153) },
get red() { return new Color(255, 0, 0) },
get rosybrown() { return new Color(188, 143, 143) },
get royalblue() { return new Color(65, 105, 225) },
get saddlebrown() { return new Color(139, 69, 19) },
get salmon() { return new Color(250, 128, 114) },
get sandybrown() { return new Color(244, 164, 96) },
get seagreen() { return new Color(46, 139, 87) },
get seashell() { return new Color(255, 245, 238) },
get sienna() { return new Color(160, 82, 45) },
get silver() { return new Color(192, 192, 192) },
get skyblue() { return new Color(135, 206, 235) },
get slateblue() { return new Color(106, 90, 205) },
get slategray() { return new Color(112, 128, 144) },
get snow() { return new Color(255, 250, 250) },
get springgreen() { return new Color(0, 255, 127) },
get steelblue() { return new Color(70, 130, 180) },
get tan() { return new Color(210, 180, 140) },
get teal() { return new Color(0, 128, 128) },
get thistle() { return new Color(216, 191, 216) },
get tomato() { return new Color(255, 99, 71) },
get turquoise() { return new Color(64, 224, 208) },
get violet() { return new Color(238, 130, 238) },
get wheat() { return new Color(245, 222, 179) },
get white() { return new Color(255, 255, 255) },
get whitesmoke() { return new Color(245, 245, 245) },
get yellow() { return new Color(255, 255, 0) },
get yellowgreen() { return new Color(154, 205, 50) }
}
export function RGBToHSL(r, g, b) {
return handleTryCatch({
n: "RGBToHSL",
c: !isNum(r) || !isNum(g) || !isNum(b),
p: { r, g, b },
f: null,
e: () => {
// Normalize RGB values
const nr = clamp(r, 0, 255) / 255;
const ng = clamp(g, 0, 255) / 255;
const nb = clamp(b, 0, 255) / 255;
// min/max
const min = Math.min(nr, ng, nb);
const max = Math.max(nr, ng, nb);
// defaults
let h, s = 0, l = (max + min) / 2;
if (max === min) {
// Achromatic (grey)
h = 0;
} else {
const d = max - min;
s = d / (1 - Math.abs(2 * l - 1));
if (max === nr) h = ((ng - nb) / d + (ng < nb ? 6 : 0)) * 60; // Corrected hue calculation
else if (max === ng) h = ((nb - nr) / d + 2) * 60; // Corrected hue calculation
else h = ((nr - ng) / d + 4) * 60; // Corrected hue calculation
}
s *= 100;
l *= 100;
// Ensure h, s, and l are within valid ranges
h = clamp(h, 0, 360);
s = clamp(s, 0, 100);
l = clamp(l, 0, 100);
return { h: Math.round(h), s: Math.round(s), l: Math.round(l) };
}
});
}
export function HSLtoRGB(hue, sat, light) {
return handleTryCatch({
n: "HSLtoRGB",
c: !isNum(hue) || !isNum(sat) || !isNum(light),
p: { hue, sat, light },
f: null,
e: () => {
// Clamp
hue = clamp(hue, 0, 360);
// Normalize saturation and lightness
sat /= 100;
light /= 100;
// STUFF IDK
let t1, t2, r, g, b;
hue /= 60;
if (light <= 0.5) {
t2 = light * (sat + 1);
} else {
t2 = light + sat - (light * sat);
}
t1 = light * 2 - t2;
// Helper function to convert hue to RGB value
const hueToRgb = (t1, t2, hue) => {
if (hue < 0) hue += 6;
if (hue >= 6) hue -= 6;
if (hue < 1) return (t2 - t1) * hue + t1;
else if (hue < 3) return t2;
else if (hue < 4) return (t2 - t1) * (4 - hue) + t1;
else return t1;
}
r = hueToRgb(t1, t2, hue + 2) * 255;
g = hueToRgb(t1, t2, hue) * 255;
b = hueToRgb(t1, t2, hue - 2) * 255;
// Clamp RGB values
r = clamp(r, 0, 255);
g = clamp(g, 0, 255);
b = clamp(b, 0, 255);
return { r: Math.round(r), g: Math.round(g), b: Math.round(b) };
}
});
}
export function generateColorList(count = 1, { saturation = 100, lightness = 50 } = {}) {
return handleTryCatch({
n: "generatColorList",
c: !isNum(count) || !isNum(saturation) || !isNum(lightness),
p: { count, saturation, lightness },
f: null,
e: () => {
saturation = clamp(saturation, 0, 100);
lightness = clamp(lightness, 0, 100);
const colors = [];
for (let i = 0; i < count; i++) {
colors.push(indexColor(i, { saturation, lightness, count }));
}
return colors;
}
});
}
export function indexColor(index, { saturation = 100, lightness = 50, count = 360 } = {}) {
return handleTryCatch({
n: "indexColor",
c: !isNum(index) || !isNum(saturation) || !isNum(lightness) || !isNum(count),
p: { index, saturation, lightness, count },
f: null,
e: () => {
saturation = clamp(saturation, 0, 100)
lightness = clamp(lightness, 0, 100)
const hue = (index * (360 / count));
const rgb = HSLtoRGB(hue, saturation, lightness);
return new Color(rgb.r, rgb.g, rgb.b);
}
});
}
/**
* @returns {Color}
*/
export function randomColor({ saturation = 100, lightness = 50 } = {}) {
return handleTryCatch({
n: "randomColor",
c: !isNum(saturation) || !isNum(lightness),
p: { saturation, lightness },
f: null,
e: () => {
return indexColor(randomInt(0, 360), { saturation, lightness });
}
});
}
/**
* @returns {Color}
*/
export function randomColorSeed(seed = "", { saturation = 100, lightness = 50 } = {}) {
return handleTryCatch({
n: "randomColorSeed",
c: !isStr(seed) || !isNum(saturation) || !isNum(lightness),
p: { seed, saturation, lightness },
f: null,
e: () => {
return indexColor(randomIntSeed(seed, 1, 360), { saturation, lightness });
}
});
}
/**
* @returns {Color}
*/
export function scaleColors(perc, stops, colors, o) {
return handleTryCatch({
n: "scaleColors",
c: !isNum(perc) || !isArr(stops) || !isArr(colors) || stops.length !== colors.length,
p: { perc, stops, colors },
f: null,
e: () => {
for (let i = 0; i < stops.length; i++) {
let cS = stops[i];
let cC = new Color(colors[i]);
let nS = stops[i + 1] ?? 1;
let nC = new Color(colors[i + 1] ?? colors[i]); // Use the current color if next color is not provided
if (cS <= perc && perc < nS) {
return cC.setFade(o).scaleToColor((perc - cS) / (nS - cS), nC);
}
}
// If perc is outside the range of stops, return the color at the first or last stop
if (perc <= Math.min(...stops)) {
return new Color(colors[0]).setFade(o);
} else {
return new Color(colors[colors.length - 1]).setFade(o);
}
}
});
}
export function listColorsScale(length, stops, colors, o) {
return handleTryCatch({
n: "listColorsScale",
c: !isNum(length) || !isArr(stops) || !isArr(colors) || stops.length !== colors.length,
p: { length, stops, colors },
f: null,
e: () => {
const minStop = Math.min(...stops);
const maxStop = Math.max(...stops);
const step = (maxStop - minStop) / length;
const colorList = [];
for (let i = minStop; i <= maxStop; i += step) {
colorList.push(scaleColors(i, stops, colors, o));
}
return colorList;
}
});
}
/**
* Generate a radial gradient based on stops and colors.
* @param {number} perc - Percentage to increase the heat color in the center.
* @param {Array<number>} stops - Array of stop positions (0-1).
* @param {Array<string>} colors - Array of color values.
* @param {number} o - Opacity value (0-1).
* @returns {Array<{ color: string, percent: number }>} Array of objects representing colors and their percentages.
*/
export function radialGradientColors(perc, stops, colors, o) {
return handleTryCatch({
n: "radialGradientColors",
c: !isNum(perc) || !isArr(stops) || !isArr(colors) || stops.length !== colors.length,
p: { perc, stops, colors },
e: () => {
const gradientStops = [];
// Determine the position of the color stops
for (let i = 0; i < stops.length; i++) {
const start = i === 0 ? 0 : stops[i - 1];
const end = stops[i];
// Calculate the effective start and end positions for the color transition
const effectiveStart = (perc < start ? start : perc) * 100;
const effectiveEnd = (perc > end ? end : perc) * 100;
// Add the color stop for the current color
if (effectiveStart < effectiveEnd) {
const position = (effectiveStart + effectiveEnd) / 2;
gradientStops.push({ color: colors[i].setFade(o), percent: position });
}
}
return gradientStops;
}
});
}
/**
* Convert an array of color stops and percentages to CSS for a radial gradient.
* @param {Array<{ color: string, percent: number }>} gradientStops - Array of color stops and percentages.
* @returns {string} CSS string for the radial gradient.
*/
export function radialGradientColorsCSS(gradientStops) {
const gradientColors = gradientStops.map(stop => `${stop.color.RGBA} ${stop.percent * 100}%`);
return `radial-gradient(circle, ${gradientColors.join(', ')})`;
}
/**
* @returns {Color}
*/
export function scaleHeatColors(perc, firstColors, o) {
const data = {
stops: [0, 0.15, 0.35, 0.65, 0.9, 1],
colors: [Colors.steelblue, Colors.darkred, Colors.red, Colors.orange, Colors.yellow, Colors.white]
}
return handleTryCatch({
n: "scaleHeatColors",
c: !isNum(perc),
p: { perc },
f: null,
e: () => {
let colors = [...data.colors]; // Create a copy of colors to avoid mutating the original
if (firstColors && Array.isArray(firstColors)) {
colors.shift();
colors = [firstColors, ...colors];
}
return scaleColors(perc, data.stops, colors, o);
}
});
}
export function listHeatColors(length, firstColors, o) {
const data = {
stops: [0, 0.15, 0.35, 0.65, 0.9, 1],
colors: [Colors.steelblue, Colors.darkred, Colors.red, Colors.orange, Colors.yellow, Colors.white]
}
return handleTryCatch({
n: "listHeatColors",
c: !isNum(length),
p: { length },
f: null,
e: () => {
let colors = [...data.colors]; // Create a copy to avoid mutation
if (firstColors) {
colors = [firstColors, ...colors.slice(1)]; // Add firstColors to the beginning of colors
}
return listColorsScale(length, data.stops, colors, o);
}
});
}
export function radialGradientHeatColors(perc, firstColors, o) {
const data = {
stops: [0, 0.15, 0.35, 0.65, 0.9, 1],
colors: [Colors.steelblue, Colors.darkred, Colors.red, Colors.orange, Colors.yellow, Colors.white]
}
return handleTryCatch({
n: "radialGradientHeatColors",
c: !isNum(perc),
p: { perc },
e: () => {
let colors = [...data.colors]; // Create a copy of colors to avoid mutating the original
if (firstColors && Array.isArray(firstColors)) {
colors.shift();
colors = [firstColors, ...colors];
}
return radialGradientColors(perc, data.stops, colors, o);
}
});
}