@esmalley/ts-utils 1.0.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Arithmetic.d.ts.map +1 -0
- package/dist/cjs/Arithmetic.js +9 -0
- package/dist/cjs/Arrayifier.d.ts.map +1 -0
- package/dist/cjs/Arrayifier.js +69 -0
- package/dist/cjs/CSV.d.ts.map +1 -0
- package/dist/cjs/CSV.js +39 -0
- package/dist/cjs/Color.d.ts.map +1 -0
- package/dist/cjs/Color.js +348 -0
- package/dist/cjs/Dates.d.ts.map +1 -0
- package/dist/cjs/Dates.js +358 -0
- package/dist/cjs/Kontororu/Socket.d.ts.map +1 -0
- package/dist/cjs/Kontororu/Socket.js +221 -0
- package/dist/cjs/Kontororu.d.ts.map +1 -0
- package/dist/cjs/Kontororu.js +27 -0
- package/dist/cjs/Objector.d.ts.map +1 -0
- package/dist/cjs/Objector.js +124 -0
- package/dist/cjs/Sorter.d.ts.map +1 -0
- package/dist/cjs/Sorter.js +32 -0
- package/dist/cjs/Style.d.ts.map +1 -0
- package/dist/cjs/Style.js +475 -0
- package/dist/cjs/Text.d.ts.map +1 -0
- package/dist/cjs/Text.js +39 -0
- package/dist/{Theme.d.ts.map → cjs/Theme.d.ts.map} +1 -1
- package/dist/cjs/Theme.js +507 -0
- package/dist/cjs/Toaster.d.ts.map +1 -0
- package/dist/cjs/Toaster.js +49 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +27 -0
- package/dist/esm/Arithmetic.d.ts +4 -0
- package/dist/esm/Arithmetic.d.ts.map +1 -0
- package/dist/esm/Arrayifier.d.ts +29 -0
- package/dist/esm/Arrayifier.d.ts.map +1 -0
- package/dist/esm/CSV.d.ts +10 -0
- package/dist/esm/CSV.d.ts.map +1 -0
- package/dist/esm/Color.d.ts +93 -0
- package/dist/esm/Color.d.ts.map +1 -0
- package/dist/esm/Dates.d.ts +51 -0
- package/dist/esm/Dates.d.ts.map +1 -0
- package/dist/esm/Kontororu/Socket.d.ts +44 -0
- package/dist/esm/Kontororu/Socket.d.ts.map +1 -0
- package/dist/esm/Kontororu.d.ts +8 -0
- package/dist/esm/Kontororu.d.ts.map +1 -0
- package/dist/esm/Objector.d.ts +32 -0
- package/dist/esm/Objector.d.ts.map +1 -0
- package/dist/esm/Sorter.d.ts +8 -0
- package/dist/esm/Sorter.d.ts.map +1 -0
- package/dist/esm/Style.d.ts +63 -0
- package/dist/esm/Style.d.ts.map +1 -0
- package/dist/esm/Text.d.ts +5 -0
- package/dist/esm/Text.d.ts.map +1 -0
- package/dist/esm/Theme.d.ts +1413 -0
- package/dist/esm/Theme.d.ts.map +1 -0
- package/dist/esm/Toaster.d.ts +24 -0
- package/dist/esm/Toaster.d.ts.map +1 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/package.json +7 -5
- package/dist/Arithmetic.d.ts.map +0 -1
- package/dist/Arrayifier.d.ts.map +0 -1
- package/dist/CSV.d.ts.map +0 -1
- package/dist/Color.d.ts.map +0 -1
- package/dist/Dates.d.ts.map +0 -1
- package/dist/Kontororu/Socket.d.ts.map +0 -1
- package/dist/Kontororu.d.ts.map +0 -1
- package/dist/Objector.d.ts.map +0 -1
- package/dist/Sorter.d.ts.map +0 -1
- package/dist/Style.d.ts.map +0 -1
- package/dist/Text.d.ts.map +0 -1
- package/dist/Toaster.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- /package/dist/{Arithmetic.d.ts → cjs/Arithmetic.d.ts} +0 -0
- /package/dist/{Arrayifier.d.ts → cjs/Arrayifier.d.ts} +0 -0
- /package/dist/{CSV.d.ts → cjs/CSV.d.ts} +0 -0
- /package/dist/{Color.d.ts → cjs/Color.d.ts} +0 -0
- /package/dist/{Dates.d.ts → cjs/Dates.d.ts} +0 -0
- /package/dist/{Kontororu → cjs/Kontororu}/Socket.d.ts +0 -0
- /package/dist/{Kontororu.d.ts → cjs/Kontororu.d.ts} +0 -0
- /package/dist/{Objector.d.ts → cjs/Objector.d.ts} +0 -0
- /package/dist/{Sorter.d.ts → cjs/Sorter.d.ts} +0 -0
- /package/dist/{Style.d.ts → cjs/Style.d.ts} +0 -0
- /package/dist/{Text.d.ts → cjs/Text.d.ts} +0 -0
- /package/dist/{Theme.d.ts → cjs/Theme.d.ts} +0 -0
- /package/dist/{Toaster.d.ts → cjs/Toaster.d.ts} +0 -0
- /package/dist/{index.d.ts → cjs/index.d.ts} +0 -0
- /package/dist/{Arithmetic.js → esm/Arithmetic.js} +0 -0
- /package/dist/{Arrayifier.js → esm/Arrayifier.js} +0 -0
- /package/dist/{CSV.js → esm/CSV.js} +0 -0
- /package/dist/{Color.js → esm/Color.js} +0 -0
- /package/dist/{Dates.js → esm/Dates.js} +0 -0
- /package/dist/{Kontororu → esm/Kontororu}/Socket.js +0 -0
- /package/dist/{Kontororu.js → esm/Kontororu.js} +0 -0
- /package/dist/{Objector.js → esm/Objector.js} +0 -0
- /package/dist/{Sorter.js → esm/Sorter.js} +0 -0
- /package/dist/{Style.js → esm/Style.js} +0 -0
- /package/dist/{Text.js → esm/Text.js} +0 -0
- /package/dist/{Theme.js → esm/Theme.js} +0 -0
- /package/dist/{Toaster.js → esm/Toaster.js} +0 -0
- /package/dist/{index.js → esm/index.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Arithmetic.d.ts","sourceRoot":"","sources":["../../src/Arithmetic.ts"],"names":[],"mappings":"AACA,qBAAa,UAAU;WACP,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;CAGtE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Arrayifier.d.ts","sourceRoot":"","sources":["../../src/Arrayifier.ts"],"names":[],"mappings":"AACA,qBAAa,UAAU;IAKrB;;;;QAII;IACJ,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC;IAkB9C;;;;;;;;;;QAUI;IACJ,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;IAqBnH;;;;;;QAMI;IACJ,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;CAOzD"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Arrayifier = void 0;
|
|
4
|
+
class Arrayifier {
|
|
5
|
+
// constructor() {
|
|
6
|
+
// }
|
|
7
|
+
/**
|
|
8
|
+
* Shuffle / ranomize elements in an array
|
|
9
|
+
* @param {array} array The array to shuffle
|
|
10
|
+
* @return array
|
|
11
|
+
*/
|
|
12
|
+
shuffle(array) {
|
|
13
|
+
let currentIndex = array.length;
|
|
14
|
+
let randomIndex;
|
|
15
|
+
// While there remain elements to shuffle.
|
|
16
|
+
while (currentIndex !== 0) {
|
|
17
|
+
// Pick a remaining element.
|
|
18
|
+
randomIndex = Math.floor(Math.random() * currentIndex);
|
|
19
|
+
currentIndex--;
|
|
20
|
+
// And swap it with the current element.
|
|
21
|
+
[array[currentIndex], array[randomIndex]] = [
|
|
22
|
+
array[randomIndex], array[currentIndex]
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
return array;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* @param {Array} arr
|
|
30
|
+
* @param {number} n
|
|
31
|
+
* @param {number} r
|
|
32
|
+
* @param {number} index
|
|
33
|
+
* @param {Array} data
|
|
34
|
+
* @param {number} i
|
|
35
|
+
* @param {Array} results
|
|
36
|
+
* @returns Array
|
|
37
|
+
*/
|
|
38
|
+
combination(arr, n, r, index, data, i, results) {
|
|
39
|
+
if (index === r) {
|
|
40
|
+
const result = [];
|
|
41
|
+
for (let j = 0; j < r; j++) {
|
|
42
|
+
result.push(data[j]);
|
|
43
|
+
}
|
|
44
|
+
results.push(result);
|
|
45
|
+
return results;
|
|
46
|
+
}
|
|
47
|
+
if (i >= n) {
|
|
48
|
+
return results;
|
|
49
|
+
}
|
|
50
|
+
data[index] = arr[i];
|
|
51
|
+
this.combination(arr, n, r, index + 1, data, i + 1, results);
|
|
52
|
+
this.combination(arr, n, r, index, data, i + 1, results);
|
|
53
|
+
return results;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get all combinations of every value in the provided array for a specified number
|
|
57
|
+
* @param {Array} arr
|
|
58
|
+
* @param {number} n
|
|
59
|
+
* @param {number} r
|
|
60
|
+
* @returns Array
|
|
61
|
+
*/
|
|
62
|
+
getCombinations(arr, n, r) {
|
|
63
|
+
const data = new Array(r);
|
|
64
|
+
let results = [];
|
|
65
|
+
results = this.combination(arr, n, r, 0, data, 0, results);
|
|
66
|
+
return results;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.Arrayifier = Arrayifier;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CSV.d.ts","sourceRoot":"","sources":["../../src/CSV.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,qBAAa,GAAG;IACd;;OAEG;WACW,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI;CAiC5E"}
|
package/dist/cjs/CSV.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CSV = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Everything to help with CSV generation
|
|
6
|
+
*/
|
|
7
|
+
class CSV {
|
|
8
|
+
/**
|
|
9
|
+
* Convert an object to a CSV file and then download it
|
|
10
|
+
*/
|
|
11
|
+
static download(data) {
|
|
12
|
+
const rows = [];
|
|
13
|
+
let setHeaders = false;
|
|
14
|
+
let headers = [];
|
|
15
|
+
for (const id in data) {
|
|
16
|
+
const row = data[id];
|
|
17
|
+
if (!setHeaders) {
|
|
18
|
+
headers = Object.keys(row);
|
|
19
|
+
rows.push(headers.join(','));
|
|
20
|
+
setHeaders = true;
|
|
21
|
+
}
|
|
22
|
+
const values = headers.map((header) => JSON.stringify(row[header] || ''));
|
|
23
|
+
rows.push(values.join(','));
|
|
24
|
+
}
|
|
25
|
+
const content = rows.join('\n');
|
|
26
|
+
// Create a Blob and trigger download
|
|
27
|
+
const blob = new Blob([content], { type: 'text/csv' });
|
|
28
|
+
const url = URL.createObjectURL(blob);
|
|
29
|
+
const a = document.createElement('a');
|
|
30
|
+
a.href = url;
|
|
31
|
+
a.download = 'srating-data.csv';
|
|
32
|
+
// Trigger download and clean up
|
|
33
|
+
document.body.appendChild(a);
|
|
34
|
+
a.click();
|
|
35
|
+
URL.revokeObjectURL(url);
|
|
36
|
+
a.remove();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.CSV = CSV;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Color.d.ts","sourceRoot":"","sources":["../../src/Color.ts"],"names":[],"mappings":"AAIA,qBAAa,KAAK;IAKhB;;;;;;;;;OASG;WACW,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAkBrE;;OAEG;WACW,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,UAAQ;WAoFlE,gBAAgB,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;IAiBtG;;;;;OAKG;IAWH;;;;;OAKG;IAWH;;;;;;OAMG;WACW,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAY,GAAG,MAAM;IAa/D;;;;;;OAMG;WACW,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAY,GAAG,MAAM;WAalD,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAWrD;;;;;;OAMG;WACW,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAK;IAM7E;;;;OAIG;WACW,WAAW,CAAC,GAAG,EAAE,MAAM;IAYrC;;;;;OAKG;WACW,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAO5D;;;;OAIG;WACW,kBAAkB,CAAC,GAAG,EAAE,MAAM;IAmB5C;;;;OAIG;WACW,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAwBlD;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ;IAIvB,OAAO,CAAC,MAAM,CAAC,QAAQ;IAyBvB,OAAO,CAAC,MAAM,CAAC,QAAQ;IA8BvB,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAKlC,OAAO,CAAC,MAAM,CAAC,aAAa;CAU7B"}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable no-mixed-operators */
|
|
3
|
+
/* eslint-disable no-bitwise */
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.Color = void 0;
|
|
6
|
+
class Color {
|
|
7
|
+
// constructor() {
|
|
8
|
+
// }
|
|
9
|
+
/**
|
|
10
|
+
* A linear interpolator for hexadecimal colors
|
|
11
|
+
* @param {string} a
|
|
12
|
+
* @param {string} b
|
|
13
|
+
* @param {number} amount
|
|
14
|
+
* @example
|
|
15
|
+
* // returns #7F7F7F
|
|
16
|
+
* lerpColor('#000000', '#ffffff', 0.5)
|
|
17
|
+
* @return {string}
|
|
18
|
+
*/
|
|
19
|
+
static lerpColor(a, b, amount) {
|
|
20
|
+
const ah = +a.replace('#', '0x');
|
|
21
|
+
const ar = ah >> 16;
|
|
22
|
+
const ag = ah >> 8 & 0xff;
|
|
23
|
+
const ab = ah & 0xff;
|
|
24
|
+
const bh = +b.replace('#', '0x');
|
|
25
|
+
const br = bh >> 16;
|
|
26
|
+
const bg = bh >> 8 & 0xff;
|
|
27
|
+
const bb = bh & 0xff;
|
|
28
|
+
const rr = ar + amount * (br - ar);
|
|
29
|
+
const rg = ag + amount * (bg - ag);
|
|
30
|
+
const rb = ab + amount * (bb - ab);
|
|
31
|
+
return `#${((1 << 24) + (rr << 16) + (rg << 8) + rb | 0).toString(16).slice(1)}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get a color that will look readable based on a background color
|
|
35
|
+
*/
|
|
36
|
+
static getTextColor(color, backgroundColor, debug = false) {
|
|
37
|
+
// Convert hex colors to RGB
|
|
38
|
+
/*
|
|
39
|
+
let [r1, g1, b1] = Color.hexToRgb(color);
|
|
40
|
+
const [r2, g2, b2] = Color.hexToRgb(backgroundColor);
|
|
41
|
+
|
|
42
|
+
const brightnessBg = Color.calculateBrightness(r2, g2, b2);
|
|
43
|
+
|
|
44
|
+
const targetBrightness = brightnessBg > 128 ? 50 : 150; // target brightness threshold for contrast
|
|
45
|
+
|
|
46
|
+
while (true) {
|
|
47
|
+
const brightnessColor = Color.calculateBrightness(r1, g1, b1);
|
|
48
|
+
|
|
49
|
+
if (
|
|
50
|
+
(brightnessBg > 128 && brightnessColor < targetBrightness) ||
|
|
51
|
+
(brightnessBg <= 128 && brightnessColor > targetBrightness)
|
|
52
|
+
) {
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (brightnessBg > 128) {
|
|
57
|
+
r1 = Math.max(0, r1 - 25);
|
|
58
|
+
g1 = Math.max(0, g1 - 25);
|
|
59
|
+
b1 = Math.max(0, b1 - 25);
|
|
60
|
+
} else {
|
|
61
|
+
r1 = Math.min(255, r1 + 25);
|
|
62
|
+
g1 = Math.min(255, g1 + 25);
|
|
63
|
+
b1 = Math.min(255, b1 + 25);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if ((r1 === 0 && g1 === 0 && b1 === 0) || (r1 === 255 && g1 === 255 && b1 === 255)) {
|
|
67
|
+
break; // avoid infinite loop
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Convert back to hex
|
|
72
|
+
return Color.rgbToHex(r1, g1, b1);
|
|
73
|
+
*/
|
|
74
|
+
let [r, g, b] = Color.hexToRgb(color);
|
|
75
|
+
const [br, bg, bb] = Color.hexToRgb(backgroundColor);
|
|
76
|
+
const contrastTarget = 4.5;
|
|
77
|
+
if (debug) {
|
|
78
|
+
console.log('Color.getContrastRatio([r, g, b], [br, bg, bb])', Color.getContrastRatio([r, g, b], [br, bg, bb]));
|
|
79
|
+
}
|
|
80
|
+
if (Color.getContrastRatio([r, g, b], [br, bg, bb]) >= contrastTarget) {
|
|
81
|
+
return Color.rgbToHex(r, g, b);
|
|
82
|
+
}
|
|
83
|
+
const contrastToBlack = Color.getContrastRatio([0, 0, 0], [br, bg, bb]);
|
|
84
|
+
const contrastToWhite = Color.getContrastRatio([255, 255, 255], [br, bg, bb]);
|
|
85
|
+
const direction = contrastToWhite > contrastToBlack ? 'lighter' : 'darker';
|
|
86
|
+
if (debug) {
|
|
87
|
+
console.log('contrastToBlack', contrastToBlack);
|
|
88
|
+
console.log('contrastToWhite', contrastToWhite);
|
|
89
|
+
console.log('direction', direction);
|
|
90
|
+
}
|
|
91
|
+
const adjust = (c, lighter) => {
|
|
92
|
+
return lighter ? Math.min(255, c + 10) : Math.max(0, c - 10);
|
|
93
|
+
};
|
|
94
|
+
for (let i = 0; i < 25; i++) {
|
|
95
|
+
r = adjust(r, direction === 'lighter');
|
|
96
|
+
g = adjust(g, direction === 'lighter');
|
|
97
|
+
b = adjust(b, direction === 'lighter');
|
|
98
|
+
if (debug) {
|
|
99
|
+
console.log('Color.getContrastRatio([r, g, b], [br, bg, bb]) 2', Color.getContrastRatio([r, g, b], [br, bg, bb]));
|
|
100
|
+
}
|
|
101
|
+
if (Color.getContrastRatio([r, g, b], [br, bg, bb]) >= contrastTarget) {
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return Color.rgbToHex(r, g, b);
|
|
106
|
+
}
|
|
107
|
+
static getContrastRatio(rgb1, rgb2) {
|
|
108
|
+
const luminance = (r, g, b) => {
|
|
109
|
+
const a = [r, g, b].map((v) => {
|
|
110
|
+
v /= 255;
|
|
111
|
+
return v <= 0.03928
|
|
112
|
+
? v / 12.92
|
|
113
|
+
: Math.pow((v + 0.055) / 1.055, 2.4);
|
|
114
|
+
});
|
|
115
|
+
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
|
|
116
|
+
};
|
|
117
|
+
const lum1 = luminance(...rgb1) + 0.05;
|
|
118
|
+
const lum2 = luminance(...rgb2) + 0.05;
|
|
119
|
+
return lum1 > lum2 ? lum1 / lum2 : lum2 / lum1;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Take a hex (#fff) and an amount and darken the color, return a hex
|
|
123
|
+
* @param {string} hex
|
|
124
|
+
* @param {number} amount
|
|
125
|
+
* @return {string} hex
|
|
126
|
+
*/
|
|
127
|
+
// public static darken(hex: string, amount: number = 0.02): string {
|
|
128
|
+
// const [r, g, b] = this.hexToRgb(hex);
|
|
129
|
+
// const [h, s, l] = this.rgbToHsl(r, g, b);
|
|
130
|
+
// const newL = Math.max(0, (l / 100) - amount) * 100;
|
|
131
|
+
// const [r2, g2, b2] = this.hslToRgb(h, s, newL);
|
|
132
|
+
// return this.rgbToHex(r2, g2, b2);
|
|
133
|
+
// }
|
|
134
|
+
/**
|
|
135
|
+
* Take a hex (#fff) and an amount and lighten the color, return a hex
|
|
136
|
+
* @param {string} hex
|
|
137
|
+
* @param {number} amount
|
|
138
|
+
* @return {string} hex
|
|
139
|
+
*/
|
|
140
|
+
// public static lighten(hex: string, amount: number = 0.02): string {
|
|
141
|
+
// const [r, g, b] = this.hexToRgb(hex);
|
|
142
|
+
// const [h, s, l] = this.rgbToHsl(r, g, b);
|
|
143
|
+
// const newL = Math.min(1, (l / 100) + amount) * 100;
|
|
144
|
+
// const [r2, g2, b2] = this.hslToRgb(h, s, newL);
|
|
145
|
+
// return this.rgbToHex(r2, g2, b2);
|
|
146
|
+
// }
|
|
147
|
+
/**
|
|
148
|
+
* Mixes the color with black to create a Shade.
|
|
149
|
+
* Prevents the "muddy/brown" look of HSL darkening.
|
|
150
|
+
* @param {string} hex - The color to darken
|
|
151
|
+
* @param {number} amount - 0 to 1 (e.g. 0.1 is 10% darker)
|
|
152
|
+
* @return {string} hex
|
|
153
|
+
*/
|
|
154
|
+
static darken(hex, amount = 0.1) {
|
|
155
|
+
const [r, g, b] = this.hexToRgb(hex);
|
|
156
|
+
// Calculate new color by mixing with black (0)
|
|
157
|
+
// Formula: Current * (1 - amount)
|
|
158
|
+
const remaining = 1 - amount;
|
|
159
|
+
const r2 = Math.round(r * remaining);
|
|
160
|
+
const g2 = Math.round(g * remaining);
|
|
161
|
+
const b2 = Math.round(b * remaining);
|
|
162
|
+
return this.rgbToHex(r2, g2, b2);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Mixes the color with white to create a Tint.
|
|
166
|
+
* cleaner and less "washed out" than HSL lightness adjustment.
|
|
167
|
+
* @param {string} hex - The color to lighten
|
|
168
|
+
* @param {number} amount - 0 to 1 (e.g. 0.1 is 10% lighter)
|
|
169
|
+
* @return {string} hex
|
|
170
|
+
*/
|
|
171
|
+
static lighten(hex, amount = 0.1) {
|
|
172
|
+
const [r, g, b] = this.hexToRgb(hex);
|
|
173
|
+
// Calculate new color by mixing with white (255)
|
|
174
|
+
// Formula: Current + ((Target - Current) * amount)
|
|
175
|
+
const r2 = Math.round(r + (255 - r) * amount);
|
|
176
|
+
const g2 = Math.round(g + (255 - g) * amount);
|
|
177
|
+
const b2 = Math.round(b + (255 - b) * amount);
|
|
178
|
+
return this.rgbToHex(r2, g2, b2);
|
|
179
|
+
}
|
|
180
|
+
static shadeColor(hex, percent) {
|
|
181
|
+
let [r, g, b] = Color.hexToRgb(hex);
|
|
182
|
+
r = Math.min(255, Math.max(0, Math.round(r + (r * (percent / 100)))));
|
|
183
|
+
g = Math.min(255, Math.max(0, Math.round(g + (g * (percent / 100)))));
|
|
184
|
+
b = Math.min(255, Math.max(0, Math.round(b + (b * (percent / 100)))));
|
|
185
|
+
return Color.rgbToHex(r, g, b);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Are 2 colors similar to each other?
|
|
189
|
+
* @param {string} color1
|
|
190
|
+
* @param {string} color2
|
|
191
|
+
* @param {number} threshold
|
|
192
|
+
* @return {boolean}
|
|
193
|
+
*/
|
|
194
|
+
static areColorsSimilar(color1, color2, threshold = 50) {
|
|
195
|
+
const distance = Color.colorDistance(color1, color2);
|
|
196
|
+
return distance < threshold;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Inverts a hex color
|
|
200
|
+
* @param {string} hex
|
|
201
|
+
* @return {string} hex
|
|
202
|
+
*/
|
|
203
|
+
static invertColor(hex) {
|
|
204
|
+
const [r, g, b] = Color.hexToRgb(hex);
|
|
205
|
+
// Invert each color component
|
|
206
|
+
const invertedR = 255 - r;
|
|
207
|
+
const invertedG = 255 - g;
|
|
208
|
+
const invertedB = 255 - b;
|
|
209
|
+
return Color.rgbToHex(invertedR, invertedG, invertedB);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Takes a hex (#fff) and returns an rgba with the provided alpha
|
|
213
|
+
* @param {string} hex
|
|
214
|
+
* @param {number} alpha
|
|
215
|
+
* @return {string} rgba()
|
|
216
|
+
*/
|
|
217
|
+
static alphaColor(hex, alpha) {
|
|
218
|
+
const [r, g, b] = this.hexToRgb(hex);
|
|
219
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Gets analogous colors
|
|
223
|
+
* @param {string} hex
|
|
224
|
+
* @return {Array<string>}
|
|
225
|
+
*/
|
|
226
|
+
static getAnalogousColors(hex) {
|
|
227
|
+
const [r, g, b] = Color.hexToRgb(hex);
|
|
228
|
+
const [h, s, l] = Color.rgbToHsl(r, g, b);
|
|
229
|
+
const analogousColors = [];
|
|
230
|
+
const offset = 30; // Offset for analogous colors, usually 30 degrees
|
|
231
|
+
for (let i = -1; i <= 1; i++) {
|
|
232
|
+
if (i !== 0) {
|
|
233
|
+
const newHue = (h + i * offset + 360) % 360;
|
|
234
|
+
const [newR, newG, newB] = Color.hslToRgb(newHue, s, l);
|
|
235
|
+
analogousColors.push(Color.rgbToHex(newR, newG, newB));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return analogousColors;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Convert hex to rgb
|
|
242
|
+
* @param {string} hex
|
|
243
|
+
* @return {Array} rgb
|
|
244
|
+
*/
|
|
245
|
+
static hexToRgb(hex) {
|
|
246
|
+
// Remove the hash at the start if it's there
|
|
247
|
+
let h = hex.replace(/^#/, '');
|
|
248
|
+
// Handle 3-character hex codes by expanding them to 6-character
|
|
249
|
+
if (h.length === 3) {
|
|
250
|
+
h = h.split('').map((char) => { return char + char; }).join('');
|
|
251
|
+
}
|
|
252
|
+
// Ensure it's a valid 6-character hex code
|
|
253
|
+
if (h.length !== 6) {
|
|
254
|
+
throw new Error(`Invalid hex color format: ${hex}`);
|
|
255
|
+
}
|
|
256
|
+
// Parse r, g, b values
|
|
257
|
+
const bigint = parseInt(h, 16);
|
|
258
|
+
const r = (bigint >> 16) & 255;
|
|
259
|
+
const g = (bigint >> 8) & 255;
|
|
260
|
+
const b = bigint & 255;
|
|
261
|
+
return [r, g, b];
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Convert rgb to hex
|
|
265
|
+
* @param {number} r
|
|
266
|
+
* @param {number} g
|
|
267
|
+
* @param {number} b
|
|
268
|
+
* @return {string}
|
|
269
|
+
*/
|
|
270
|
+
static rgbToHex(r, g, b) {
|
|
271
|
+
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase()}`;
|
|
272
|
+
}
|
|
273
|
+
static rgbToHsl(r, g, b) {
|
|
274
|
+
r /= 255;
|
|
275
|
+
g /= 255;
|
|
276
|
+
b /= 255;
|
|
277
|
+
const max = Math.max(r, g, b);
|
|
278
|
+
const min = Math.min(r, g, b);
|
|
279
|
+
let h = 0;
|
|
280
|
+
let s = 0;
|
|
281
|
+
const l = (max + min) / 2;
|
|
282
|
+
if (max === min) {
|
|
283
|
+
h = s = 0; // achromatic
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
const d = max - min;
|
|
287
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
288
|
+
switch (max) {
|
|
289
|
+
case r:
|
|
290
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
291
|
+
break;
|
|
292
|
+
case g:
|
|
293
|
+
h = (b - r) / d + 2;
|
|
294
|
+
break;
|
|
295
|
+
case b:
|
|
296
|
+
h = (r - g) / d + 4;
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
h /= 6;
|
|
300
|
+
}
|
|
301
|
+
return [h * 360, s * 100, l * 100];
|
|
302
|
+
}
|
|
303
|
+
static hslToRgb(h, s, l) {
|
|
304
|
+
let r;
|
|
305
|
+
let g;
|
|
306
|
+
let b;
|
|
307
|
+
h /= 360;
|
|
308
|
+
s /= 100;
|
|
309
|
+
l /= 100;
|
|
310
|
+
if (s === 0) {
|
|
311
|
+
r = g = b = l; // achromatic
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
const hue2rgb = (p, q, t) => {
|
|
315
|
+
if (t < 0)
|
|
316
|
+
t += 1;
|
|
317
|
+
if (t > 1)
|
|
318
|
+
t -= 1;
|
|
319
|
+
if (t < 1 / 6)
|
|
320
|
+
return p + (q - p) * 6 * t;
|
|
321
|
+
if (t < 1 / 3)
|
|
322
|
+
return q;
|
|
323
|
+
if (t < 1 / 2)
|
|
324
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
325
|
+
return p;
|
|
326
|
+
};
|
|
327
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
328
|
+
const p = 2 * l - q;
|
|
329
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
330
|
+
g = hue2rgb(p, q, h);
|
|
331
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
332
|
+
}
|
|
333
|
+
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
|
|
334
|
+
}
|
|
335
|
+
static calculateBrightness(r, g, b) {
|
|
336
|
+
// Calculate the brightness of the color
|
|
337
|
+
return (r * 299 + g * 587 + b * 114) / 1000;
|
|
338
|
+
}
|
|
339
|
+
static colorDistance(color1, color2) {
|
|
340
|
+
const [r1, g1, b1] = Color.hexToRgb(color1);
|
|
341
|
+
const [r2, g2, b2] = Color.hexToRgb(color2);
|
|
342
|
+
const dr = r1 - r2;
|
|
343
|
+
const dg = g1 - g2;
|
|
344
|
+
const db = b1 - b2;
|
|
345
|
+
return Math.sqrt(dr * dr + dg * dg + db * db);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
exports.Color = Color;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dates.d.ts","sourceRoot":"","sources":["../../src/Dates.ts"],"names":[],"mappings":"AAIA,qBAAa,KAAK;WAYF,KAAK,CACjB,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,EAC/C,GAAG,UAAQ,GACV,IAAI;WA8FO,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;WAKvC,cAAc,IAAI,MAAM,EAAE;WAI1B,SAAS,IAAI,MAAM,EAAE;WAIrB,YAAY,IAAI,MAAM,EAAE;WAIxB,OAAO,IAAI,MAAM,EAAE;IAIjC;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;WACW,MAAM,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM;WAgG/C,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS;WAkChG,QAAQ,CACpB,IAAI,EAAE,IAAI,GAAG,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS;WAK3C,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IA6BzC;;OAEG;WACW,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI;WA+B/E,WAAW;WAIX,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;WAMjC,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;WAOnC,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;WAWlC,SAAS,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM;WAepD,WAAW,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM;WAQtD,UAAU,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM;CAMpE"}
|