UNPKG

@exabytellc/utils

Version:

EB react utils to make everything a little easier!

487 lines (444 loc) 18.5 kB
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); } }); }