@oscarpalmer/atoms 0.39.0 → 0.40.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/js/colour.js +185 -0
- package/dist/js/colour.mjs +178 -0
- package/dist/js/index.js +213 -38
- package/dist/js/index.mjs +1 -0
- package/dist/js/random.js +0 -1
- package/dist/js/random.mjs +0 -1
- package/package.json +1 -1
- package/src/js/colour.ts +338 -0
- package/src/js/index.ts +1 -0
- package/src/js/random.ts +0 -2
- package/types/colour.d.ts +101 -0
- package/types/index.d.ts +1 -0
- package/types/random.d.ts +0 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// src/js/number.ts
|
|
2
|
+
function clamp(value, min, max, loop) {
|
|
3
|
+
if (value < min) {
|
|
4
|
+
return loop === true ? max : min;
|
|
5
|
+
}
|
|
6
|
+
return value > max ? loop === true ? min : max : value;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// src/js/colour.ts
|
|
10
|
+
var createHex = function(original) {
|
|
11
|
+
let value = original.slice();
|
|
12
|
+
const instance = Object.create({
|
|
13
|
+
toHsl() {
|
|
14
|
+
return hexToRgb(value).toHsl();
|
|
15
|
+
},
|
|
16
|
+
toRgb() {
|
|
17
|
+
return hexToRgb(value);
|
|
18
|
+
},
|
|
19
|
+
toString() {
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(instance, "value", {
|
|
24
|
+
get() {
|
|
25
|
+
return value.slice();
|
|
26
|
+
},
|
|
27
|
+
set(hex) {
|
|
28
|
+
if (anyPattern.test(hex)) {
|
|
29
|
+
value = `#${getHex(hex)}`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return instance;
|
|
34
|
+
};
|
|
35
|
+
var createHsl = function(original) {
|
|
36
|
+
const value = { ...original };
|
|
37
|
+
const instance = Object.create({
|
|
38
|
+
toHex() {
|
|
39
|
+
return hslToRgb(value).toHex();
|
|
40
|
+
},
|
|
41
|
+
toRgb() {
|
|
42
|
+
return hslToRgb(value);
|
|
43
|
+
},
|
|
44
|
+
toString() {
|
|
45
|
+
return `hsl(${value.hue}, ${value.saturation}%, ${value.lightness}%)`;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperties(instance, {
|
|
49
|
+
hue: createProperty(value, "hue", 0, 360),
|
|
50
|
+
lightness: createProperty(value, "lightness", 0, 100),
|
|
51
|
+
saturation: createProperty(value, "saturation", 0, 100),
|
|
52
|
+
value: { value }
|
|
53
|
+
});
|
|
54
|
+
return instance;
|
|
55
|
+
};
|
|
56
|
+
var createProperty = function(store, key, min, max) {
|
|
57
|
+
return {
|
|
58
|
+
get() {
|
|
59
|
+
return store[key];
|
|
60
|
+
},
|
|
61
|
+
set(value) {
|
|
62
|
+
store[key] = clamp(value, min, max);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
var createRgb = function(original) {
|
|
67
|
+
const value = { ...original };
|
|
68
|
+
const instance = Object.create({
|
|
69
|
+
toHex() {
|
|
70
|
+
return rgbToHex(value);
|
|
71
|
+
},
|
|
72
|
+
toHsl() {
|
|
73
|
+
return rgbToHsl(value);
|
|
74
|
+
},
|
|
75
|
+
toString() {
|
|
76
|
+
return `rgb(${value.red}, ${value.green}, ${value.blue})`;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
Object.defineProperties(instance, {
|
|
80
|
+
blue: createProperty(value, "blue", 0, 255),
|
|
81
|
+
green: createProperty(value, "green", 0, 255),
|
|
82
|
+
red: createProperty(value, "red", 0, 255),
|
|
83
|
+
value: { value }
|
|
84
|
+
});
|
|
85
|
+
return instance;
|
|
86
|
+
};
|
|
87
|
+
function getForegroundColour(value) {
|
|
88
|
+
const values = [value.blue / 255, value.green / 255, value.red / 255];
|
|
89
|
+
for (let colour of values) {
|
|
90
|
+
if (colour <= 0.03928) {
|
|
91
|
+
colour /= 12.92;
|
|
92
|
+
} else {
|
|
93
|
+
colour = ((colour + 0.055) / 1.055) ** 2.4;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const luminance = 0.2126 * values[2] + 0.7152 * values[1] + 0.0722 * values[0];
|
|
97
|
+
return luminance > 0.625 ? "black" : "white";
|
|
98
|
+
}
|
|
99
|
+
var getHex = function(value) {
|
|
100
|
+
const normalised = value.replace(/^#/, "");
|
|
101
|
+
return normalised.length === 3 ? normalised.split("").map((character) => character.repeat(2)).join("") : normalised;
|
|
102
|
+
};
|
|
103
|
+
function hexToRgb(value) {
|
|
104
|
+
const hex = anyPattern.test(value) ? getHex(value) : "";
|
|
105
|
+
const pairs = groupedPattern.exec(hex) ?? [];
|
|
106
|
+
const rgb = [];
|
|
107
|
+
const { length } = pairs;
|
|
108
|
+
for (let index = 1;index < length; index += 1) {
|
|
109
|
+
rgb.push(Number.parseInt(pairs[index], 16));
|
|
110
|
+
}
|
|
111
|
+
return createRgb({ blue: rgb[2] ?? 0, green: rgb[1] ?? 0, red: rgb[0] ?? 0 });
|
|
112
|
+
}
|
|
113
|
+
function hslToRgb(value) {
|
|
114
|
+
let hue = value.hue % 360;
|
|
115
|
+
if (hue < 0) {
|
|
116
|
+
hue += 360;
|
|
117
|
+
}
|
|
118
|
+
const saturation = value.saturation / 100;
|
|
119
|
+
const lightness = value.lightness / 100;
|
|
120
|
+
function get(value2) {
|
|
121
|
+
const part = (value2 + hue / 30) % 12;
|
|
122
|
+
const mod = saturation * Math.min(lightness, 1 - lightness);
|
|
123
|
+
return lightness - mod * Math.max(-1, Math.min(part - 3, 9 - part, 1));
|
|
124
|
+
}
|
|
125
|
+
return createRgb({
|
|
126
|
+
blue: clamp(Math.round(get(4) * 255), 0, 255),
|
|
127
|
+
green: clamp(Math.round(get(8) * 255), 0, 255),
|
|
128
|
+
red: clamp(Math.round(get(0) * 255), 0, 255)
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function rgbToHex(value) {
|
|
132
|
+
return createHex(`#${[value.red, value.green, value.blue].map((colour) => {
|
|
133
|
+
const hex = colour.toString(16);
|
|
134
|
+
return hex.length === 1 ? `0${hex}` : hex;
|
|
135
|
+
}).join("")}`);
|
|
136
|
+
}
|
|
137
|
+
function rgbToHsl(rgb) {
|
|
138
|
+
const blue = rgb.blue / 255;
|
|
139
|
+
const green = rgb.green / 255;
|
|
140
|
+
const red = rgb.red / 255;
|
|
141
|
+
const max = Math.max(blue, green, red);
|
|
142
|
+
const min = Math.min(blue, green, red);
|
|
143
|
+
const delta = max - min;
|
|
144
|
+
const lightness = (min + max) / 2;
|
|
145
|
+
let hue = 0;
|
|
146
|
+
let saturation = 0;
|
|
147
|
+
if (delta !== 0) {
|
|
148
|
+
saturation = lightness === 0 || lightness === 1 ? 0 : (max - lightness) / Math.min(lightness, 1 - lightness);
|
|
149
|
+
switch (max) {
|
|
150
|
+
case blue:
|
|
151
|
+
hue = (red - green) / delta + 4;
|
|
152
|
+
break;
|
|
153
|
+
case green:
|
|
154
|
+
hue = (blue - red) / delta + 2;
|
|
155
|
+
break;
|
|
156
|
+
case red:
|
|
157
|
+
hue = (green - blue) / delta + (green < blue ? 6 : 0);
|
|
158
|
+
break;
|
|
159
|
+
default:
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
hue *= 60;
|
|
163
|
+
}
|
|
164
|
+
if (saturation < 0) {
|
|
165
|
+
hue += 180;
|
|
166
|
+
saturation = Math.abs(saturation);
|
|
167
|
+
}
|
|
168
|
+
if (hue >= 360) {
|
|
169
|
+
hue -= 360;
|
|
170
|
+
}
|
|
171
|
+
return createHsl({
|
|
172
|
+
hue: +hue.toFixed(2),
|
|
173
|
+
lightness: +(lightness * 100).toFixed(2),
|
|
174
|
+
saturation: +(saturation * 100).toFixed(2)
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
var anyPattern = /^#*([a-f0-9]{3}){1,2}$/i;
|
|
178
|
+
var groupedPattern = /^#*([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i;
|
|
179
|
+
export {
|
|
180
|
+
rgbToHsl,
|
|
181
|
+
rgbToHex,
|
|
182
|
+
hslToRgb,
|
|
183
|
+
hexToRgb,
|
|
184
|
+
getForegroundColour
|
|
185
|
+
};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// src/js/colour.ts
|
|
2
|
+
import {clamp} from "./number";
|
|
3
|
+
var createHex = function(original) {
|
|
4
|
+
let value = original.slice();
|
|
5
|
+
const instance = Object.create({
|
|
6
|
+
toHsl() {
|
|
7
|
+
return hexToRgb(value).toHsl();
|
|
8
|
+
},
|
|
9
|
+
toRgb() {
|
|
10
|
+
return hexToRgb(value);
|
|
11
|
+
},
|
|
12
|
+
toString() {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(instance, "value", {
|
|
17
|
+
get() {
|
|
18
|
+
return value.slice();
|
|
19
|
+
},
|
|
20
|
+
set(hex) {
|
|
21
|
+
if (anyPattern.test(hex)) {
|
|
22
|
+
value = `#${getHex(hex)}`;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return instance;
|
|
27
|
+
};
|
|
28
|
+
var createHsl = function(original) {
|
|
29
|
+
const value = { ...original };
|
|
30
|
+
const instance = Object.create({
|
|
31
|
+
toHex() {
|
|
32
|
+
return hslToRgb(value).toHex();
|
|
33
|
+
},
|
|
34
|
+
toRgb() {
|
|
35
|
+
return hslToRgb(value);
|
|
36
|
+
},
|
|
37
|
+
toString() {
|
|
38
|
+
return `hsl(${value.hue}, ${value.saturation}%, ${value.lightness}%)`;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperties(instance, {
|
|
42
|
+
hue: createProperty(value, "hue", 0, 360),
|
|
43
|
+
lightness: createProperty(value, "lightness", 0, 100),
|
|
44
|
+
saturation: createProperty(value, "saturation", 0, 100),
|
|
45
|
+
value: { value }
|
|
46
|
+
});
|
|
47
|
+
return instance;
|
|
48
|
+
};
|
|
49
|
+
var createProperty = function(store, key, min, max) {
|
|
50
|
+
return {
|
|
51
|
+
get() {
|
|
52
|
+
return store[key];
|
|
53
|
+
},
|
|
54
|
+
set(value) {
|
|
55
|
+
store[key] = clamp(value, min, max);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
var createRgb = function(original) {
|
|
60
|
+
const value = { ...original };
|
|
61
|
+
const instance = Object.create({
|
|
62
|
+
toHex() {
|
|
63
|
+
return rgbToHex(value);
|
|
64
|
+
},
|
|
65
|
+
toHsl() {
|
|
66
|
+
return rgbToHsl(value);
|
|
67
|
+
},
|
|
68
|
+
toString() {
|
|
69
|
+
return `rgb(${value.red}, ${value.green}, ${value.blue})`;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperties(instance, {
|
|
73
|
+
blue: createProperty(value, "blue", 0, 255),
|
|
74
|
+
green: createProperty(value, "green", 0, 255),
|
|
75
|
+
red: createProperty(value, "red", 0, 255),
|
|
76
|
+
value: { value }
|
|
77
|
+
});
|
|
78
|
+
return instance;
|
|
79
|
+
};
|
|
80
|
+
function getForegroundColour(value) {
|
|
81
|
+
const values = [value.blue / 255, value.green / 255, value.red / 255];
|
|
82
|
+
for (let colour of values) {
|
|
83
|
+
if (colour <= 0.03928) {
|
|
84
|
+
colour /= 12.92;
|
|
85
|
+
} else {
|
|
86
|
+
colour = ((colour + 0.055) / 1.055) ** 2.4;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const luminance = 0.2126 * values[2] + 0.7152 * values[1] + 0.0722 * values[0];
|
|
90
|
+
return luminance > 0.625 ? "black" : "white";
|
|
91
|
+
}
|
|
92
|
+
var getHex = function(value) {
|
|
93
|
+
const normalised = value.replace(/^#/, "");
|
|
94
|
+
return normalised.length === 3 ? normalised.split("").map((character) => character.repeat(2)).join("") : normalised;
|
|
95
|
+
};
|
|
96
|
+
function hexToRgb(value) {
|
|
97
|
+
const hex = anyPattern.test(value) ? getHex(value) : "";
|
|
98
|
+
const pairs = groupedPattern.exec(hex) ?? [];
|
|
99
|
+
const rgb = [];
|
|
100
|
+
const { length } = pairs;
|
|
101
|
+
for (let index = 1;index < length; index += 1) {
|
|
102
|
+
rgb.push(Number.parseInt(pairs[index], 16));
|
|
103
|
+
}
|
|
104
|
+
return createRgb({ blue: rgb[2] ?? 0, green: rgb[1] ?? 0, red: rgb[0] ?? 0 });
|
|
105
|
+
}
|
|
106
|
+
function hslToRgb(value) {
|
|
107
|
+
let hue = value.hue % 360;
|
|
108
|
+
if (hue < 0) {
|
|
109
|
+
hue += 360;
|
|
110
|
+
}
|
|
111
|
+
const saturation = value.saturation / 100;
|
|
112
|
+
const lightness = value.lightness / 100;
|
|
113
|
+
function get(value2) {
|
|
114
|
+
const part = (value2 + hue / 30) % 12;
|
|
115
|
+
const mod = saturation * Math.min(lightness, 1 - lightness);
|
|
116
|
+
return lightness - mod * Math.max(-1, Math.min(part - 3, 9 - part, 1));
|
|
117
|
+
}
|
|
118
|
+
return createRgb({
|
|
119
|
+
blue: clamp(Math.round(get(4) * 255), 0, 255),
|
|
120
|
+
green: clamp(Math.round(get(8) * 255), 0, 255),
|
|
121
|
+
red: clamp(Math.round(get(0) * 255), 0, 255)
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
function rgbToHex(value) {
|
|
125
|
+
return createHex(`#${[value.red, value.green, value.blue].map((colour) => {
|
|
126
|
+
const hex = colour.toString(16);
|
|
127
|
+
return hex.length === 1 ? `0${hex}` : hex;
|
|
128
|
+
}).join("")}`);
|
|
129
|
+
}
|
|
130
|
+
function rgbToHsl(rgb) {
|
|
131
|
+
const blue = rgb.blue / 255;
|
|
132
|
+
const green = rgb.green / 255;
|
|
133
|
+
const red = rgb.red / 255;
|
|
134
|
+
const max = Math.max(blue, green, red);
|
|
135
|
+
const min = Math.min(blue, green, red);
|
|
136
|
+
const delta = max - min;
|
|
137
|
+
const lightness = (min + max) / 2;
|
|
138
|
+
let hue = 0;
|
|
139
|
+
let saturation = 0;
|
|
140
|
+
if (delta !== 0) {
|
|
141
|
+
saturation = lightness === 0 || lightness === 1 ? 0 : (max - lightness) / Math.min(lightness, 1 - lightness);
|
|
142
|
+
switch (max) {
|
|
143
|
+
case blue:
|
|
144
|
+
hue = (red - green) / delta + 4;
|
|
145
|
+
break;
|
|
146
|
+
case green:
|
|
147
|
+
hue = (blue - red) / delta + 2;
|
|
148
|
+
break;
|
|
149
|
+
case red:
|
|
150
|
+
hue = (green - blue) / delta + (green < blue ? 6 : 0);
|
|
151
|
+
break;
|
|
152
|
+
default:
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
hue *= 60;
|
|
156
|
+
}
|
|
157
|
+
if (saturation < 0) {
|
|
158
|
+
hue += 180;
|
|
159
|
+
saturation = Math.abs(saturation);
|
|
160
|
+
}
|
|
161
|
+
if (hue >= 360) {
|
|
162
|
+
hue -= 360;
|
|
163
|
+
}
|
|
164
|
+
return createHsl({
|
|
165
|
+
hue: +hue.toFixed(2),
|
|
166
|
+
lightness: +(lightness * 100).toFixed(2),
|
|
167
|
+
saturation: +(saturation * 100).toFixed(2)
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
var anyPattern = /^#*([a-f0-9]{3}){1,2}$/i;
|
|
171
|
+
var groupedPattern = /^#*([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i;
|
|
172
|
+
export {
|
|
173
|
+
rgbToHsl,
|
|
174
|
+
rgbToHex,
|
|
175
|
+
hslToRgb,
|
|
176
|
+
hexToRgb,
|
|
177
|
+
getForegroundColour
|
|
178
|
+
};
|
package/dist/js/index.js
CHANGED
|
@@ -132,6 +132,214 @@ function splice(array, start, amountOrValues, values) {
|
|
|
132
132
|
function unique(array, key) {
|
|
133
133
|
return _findValues("unique", array, undefined, key);
|
|
134
134
|
}
|
|
135
|
+
// src/js/number.ts
|
|
136
|
+
function between(value, min, max) {
|
|
137
|
+
return value >= min && value <= max;
|
|
138
|
+
}
|
|
139
|
+
function clamp(value, min, max, loop) {
|
|
140
|
+
if (value < min) {
|
|
141
|
+
return loop === true ? max : min;
|
|
142
|
+
}
|
|
143
|
+
return value > max ? loop === true ? min : max : value;
|
|
144
|
+
}
|
|
145
|
+
function getNumber(value) {
|
|
146
|
+
if (typeof value === "number") {
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
if (typeof value === "symbol") {
|
|
150
|
+
return Number.NaN;
|
|
151
|
+
}
|
|
152
|
+
let parsed = value?.valueOf?.() ?? value;
|
|
153
|
+
if (typeof parsed === "object") {
|
|
154
|
+
parsed = parsed?.toString() ?? parsed;
|
|
155
|
+
}
|
|
156
|
+
if (typeof parsed !== "string") {
|
|
157
|
+
return parsed == null ? Number.NaN : typeof parsed === "number" ? parsed : +parsed;
|
|
158
|
+
}
|
|
159
|
+
if (/^\s*0+\s*$/.test(parsed)) {
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
162
|
+
const trimmed = parsed.trim();
|
|
163
|
+
if (trimmed.length === 0) {
|
|
164
|
+
return Number.NaN;
|
|
165
|
+
}
|
|
166
|
+
const isBinary = /^0b[01]+$/i.test(trimmed);
|
|
167
|
+
if (isBinary || /^0o[0-7]+$/i.test(trimmed)) {
|
|
168
|
+
return Number.parseInt(trimmed.slice(2), isBinary ? 2 : 8);
|
|
169
|
+
}
|
|
170
|
+
return +(/^0x[0-9a-f]+$/i.test(trimmed) ? trimmed : trimmed.replace(/_/g, ""));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// src/js/colour.ts
|
|
174
|
+
var createHex = function(original) {
|
|
175
|
+
let value = original.slice();
|
|
176
|
+
const instance = Object.create({
|
|
177
|
+
toHsl() {
|
|
178
|
+
return hexToRgb(value).toHsl();
|
|
179
|
+
},
|
|
180
|
+
toRgb() {
|
|
181
|
+
return hexToRgb(value);
|
|
182
|
+
},
|
|
183
|
+
toString() {
|
|
184
|
+
return value;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
Object.defineProperty(instance, "value", {
|
|
188
|
+
get() {
|
|
189
|
+
return value.slice();
|
|
190
|
+
},
|
|
191
|
+
set(hex) {
|
|
192
|
+
if (anyPattern.test(hex)) {
|
|
193
|
+
value = `#${getHex(hex)}`;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
return instance;
|
|
198
|
+
};
|
|
199
|
+
var createHsl = function(original) {
|
|
200
|
+
const value = { ...original };
|
|
201
|
+
const instance = Object.create({
|
|
202
|
+
toHex() {
|
|
203
|
+
return hslToRgb(value).toHex();
|
|
204
|
+
},
|
|
205
|
+
toRgb() {
|
|
206
|
+
return hslToRgb(value);
|
|
207
|
+
},
|
|
208
|
+
toString() {
|
|
209
|
+
return `hsl(${value.hue}, ${value.saturation}%, ${value.lightness}%)`;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
Object.defineProperties(instance, {
|
|
213
|
+
hue: createProperty(value, "hue", 0, 360),
|
|
214
|
+
lightness: createProperty(value, "lightness", 0, 100),
|
|
215
|
+
saturation: createProperty(value, "saturation", 0, 100),
|
|
216
|
+
value: { value }
|
|
217
|
+
});
|
|
218
|
+
return instance;
|
|
219
|
+
};
|
|
220
|
+
var createProperty = function(store, key, min, max) {
|
|
221
|
+
return {
|
|
222
|
+
get() {
|
|
223
|
+
return store[key];
|
|
224
|
+
},
|
|
225
|
+
set(value) {
|
|
226
|
+
store[key] = clamp(value, min, max);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
var createRgb = function(original) {
|
|
231
|
+
const value = { ...original };
|
|
232
|
+
const instance = Object.create({
|
|
233
|
+
toHex() {
|
|
234
|
+
return rgbToHex(value);
|
|
235
|
+
},
|
|
236
|
+
toHsl() {
|
|
237
|
+
return rgbToHsl(value);
|
|
238
|
+
},
|
|
239
|
+
toString() {
|
|
240
|
+
return `rgb(${value.red}, ${value.green}, ${value.blue})`;
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
Object.defineProperties(instance, {
|
|
244
|
+
blue: createProperty(value, "blue", 0, 255),
|
|
245
|
+
green: createProperty(value, "green", 0, 255),
|
|
246
|
+
red: createProperty(value, "red", 0, 255),
|
|
247
|
+
value: { value }
|
|
248
|
+
});
|
|
249
|
+
return instance;
|
|
250
|
+
};
|
|
251
|
+
function getForegroundColour(value) {
|
|
252
|
+
const values = [value.blue / 255, value.green / 255, value.red / 255];
|
|
253
|
+
for (let colour of values) {
|
|
254
|
+
if (colour <= 0.03928) {
|
|
255
|
+
colour /= 12.92;
|
|
256
|
+
} else {
|
|
257
|
+
colour = ((colour + 0.055) / 1.055) ** 2.4;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
const luminance = 0.2126 * values[2] + 0.7152 * values[1] + 0.0722 * values[0];
|
|
261
|
+
return luminance > 0.625 ? "black" : "white";
|
|
262
|
+
}
|
|
263
|
+
var getHex = function(value) {
|
|
264
|
+
const normalised = value.replace(/^#/, "");
|
|
265
|
+
return normalised.length === 3 ? normalised.split("").map((character) => character.repeat(2)).join("") : normalised;
|
|
266
|
+
};
|
|
267
|
+
function hexToRgb(value) {
|
|
268
|
+
const hex = anyPattern.test(value) ? getHex(value) : "";
|
|
269
|
+
const pairs = groupedPattern.exec(hex) ?? [];
|
|
270
|
+
const rgb = [];
|
|
271
|
+
const { length } = pairs;
|
|
272
|
+
for (let index = 1;index < length; index += 1) {
|
|
273
|
+
rgb.push(Number.parseInt(pairs[index], 16));
|
|
274
|
+
}
|
|
275
|
+
return createRgb({ blue: rgb[2] ?? 0, green: rgb[1] ?? 0, red: rgb[0] ?? 0 });
|
|
276
|
+
}
|
|
277
|
+
function hslToRgb(value) {
|
|
278
|
+
let hue = value.hue % 360;
|
|
279
|
+
if (hue < 0) {
|
|
280
|
+
hue += 360;
|
|
281
|
+
}
|
|
282
|
+
const saturation = value.saturation / 100;
|
|
283
|
+
const lightness = value.lightness / 100;
|
|
284
|
+
function get(value2) {
|
|
285
|
+
const part = (value2 + hue / 30) % 12;
|
|
286
|
+
const mod = saturation * Math.min(lightness, 1 - lightness);
|
|
287
|
+
return lightness - mod * Math.max(-1, Math.min(part - 3, 9 - part, 1));
|
|
288
|
+
}
|
|
289
|
+
return createRgb({
|
|
290
|
+
blue: clamp(Math.round(get(4) * 255), 0, 255),
|
|
291
|
+
green: clamp(Math.round(get(8) * 255), 0, 255),
|
|
292
|
+
red: clamp(Math.round(get(0) * 255), 0, 255)
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
function rgbToHex(value) {
|
|
296
|
+
return createHex(`#${[value.red, value.green, value.blue].map((colour) => {
|
|
297
|
+
const hex = colour.toString(16);
|
|
298
|
+
return hex.length === 1 ? `0${hex}` : hex;
|
|
299
|
+
}).join("")}`);
|
|
300
|
+
}
|
|
301
|
+
function rgbToHsl(rgb) {
|
|
302
|
+
const blue = rgb.blue / 255;
|
|
303
|
+
const green = rgb.green / 255;
|
|
304
|
+
const red = rgb.red / 255;
|
|
305
|
+
const max = Math.max(blue, green, red);
|
|
306
|
+
const min = Math.min(blue, green, red);
|
|
307
|
+
const delta = max - min;
|
|
308
|
+
const lightness = (min + max) / 2;
|
|
309
|
+
let hue = 0;
|
|
310
|
+
let saturation = 0;
|
|
311
|
+
if (delta !== 0) {
|
|
312
|
+
saturation = lightness === 0 || lightness === 1 ? 0 : (max - lightness) / Math.min(lightness, 1 - lightness);
|
|
313
|
+
switch (max) {
|
|
314
|
+
case blue:
|
|
315
|
+
hue = (red - green) / delta + 4;
|
|
316
|
+
break;
|
|
317
|
+
case green:
|
|
318
|
+
hue = (blue - red) / delta + 2;
|
|
319
|
+
break;
|
|
320
|
+
case red:
|
|
321
|
+
hue = (green - blue) / delta + (green < blue ? 6 : 0);
|
|
322
|
+
break;
|
|
323
|
+
default:
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
hue *= 60;
|
|
327
|
+
}
|
|
328
|
+
if (saturation < 0) {
|
|
329
|
+
hue += 180;
|
|
330
|
+
saturation = Math.abs(saturation);
|
|
331
|
+
}
|
|
332
|
+
if (hue >= 360) {
|
|
333
|
+
hue -= 360;
|
|
334
|
+
}
|
|
335
|
+
return createHsl({
|
|
336
|
+
hue: +hue.toFixed(2),
|
|
337
|
+
lightness: +(lightness * 100).toFixed(2),
|
|
338
|
+
saturation: +(saturation * 100).toFixed(2)
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
var anyPattern = /^#*([a-f0-9]{3}){1,2}$/i;
|
|
342
|
+
var groupedPattern = /^#*([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i;
|
|
135
343
|
// src/js/element/index.ts
|
|
136
344
|
var _findElements = function(selector, context, single) {
|
|
137
345
|
const callback = single ? document.querySelector : document.querySelectorAll;
|
|
@@ -426,43 +634,6 @@ function isPlainObject(value) {
|
|
|
426
634
|
function isPrimitive(value) {
|
|
427
635
|
return value == null || /^(bigint|boolean|number|string|symbol)$/.test(typeof value);
|
|
428
636
|
}
|
|
429
|
-
// src/js/number.ts
|
|
430
|
-
function between(value, min, max) {
|
|
431
|
-
return value >= min && value <= max;
|
|
432
|
-
}
|
|
433
|
-
function clamp(value, min, max, loop) {
|
|
434
|
-
if (value < min) {
|
|
435
|
-
return loop === true ? max : min;
|
|
436
|
-
}
|
|
437
|
-
return value > max ? loop === true ? min : max : value;
|
|
438
|
-
}
|
|
439
|
-
function getNumber(value) {
|
|
440
|
-
if (typeof value === "number") {
|
|
441
|
-
return value;
|
|
442
|
-
}
|
|
443
|
-
if (typeof value === "symbol") {
|
|
444
|
-
return Number.NaN;
|
|
445
|
-
}
|
|
446
|
-
let parsed = value?.valueOf?.() ?? value;
|
|
447
|
-
if (typeof parsed === "object") {
|
|
448
|
-
parsed = parsed?.toString() ?? parsed;
|
|
449
|
-
}
|
|
450
|
-
if (typeof parsed !== "string") {
|
|
451
|
-
return parsed == null ? Number.NaN : typeof parsed === "number" ? parsed : +parsed;
|
|
452
|
-
}
|
|
453
|
-
if (/^\s*0+\s*$/.test(parsed)) {
|
|
454
|
-
return 0;
|
|
455
|
-
}
|
|
456
|
-
const trimmed = parsed.trim();
|
|
457
|
-
if (trimmed.length === 0) {
|
|
458
|
-
return Number.NaN;
|
|
459
|
-
}
|
|
460
|
-
const isBinary = /^0b[01]+$/i.test(trimmed);
|
|
461
|
-
if (isBinary || /^0o[0-7]+$/i.test(trimmed)) {
|
|
462
|
-
return Number.parseInt(trimmed.slice(2), isBinary ? 2 : 8);
|
|
463
|
-
}
|
|
464
|
-
return +(/^0x[0-9a-f]+$/i.test(trimmed) ? trimmed : trimmed.replace(/_/g, ""));
|
|
465
|
-
}
|
|
466
637
|
// src/js/queue.ts
|
|
467
638
|
function queue(callback) {
|
|
468
639
|
_atomic_queued.add(callback);
|
|
@@ -880,6 +1051,8 @@ export {
|
|
|
880
1051
|
titleCase,
|
|
881
1052
|
splice,
|
|
882
1053
|
setValue,
|
|
1054
|
+
rgbToHsl,
|
|
1055
|
+
rgbToHex,
|
|
883
1056
|
repeat,
|
|
884
1057
|
queue,
|
|
885
1058
|
push,
|
|
@@ -901,6 +1074,8 @@ export {
|
|
|
901
1074
|
isArrayOrPlainObject,
|
|
902
1075
|
insert,
|
|
903
1076
|
indexOf,
|
|
1077
|
+
hslToRgb,
|
|
1078
|
+
hexToRgb,
|
|
904
1079
|
groupBy,
|
|
905
1080
|
getValue,
|
|
906
1081
|
getTextDirection,
|
|
@@ -911,10 +1086,10 @@ export {
|
|
|
911
1086
|
getRandomFloat,
|
|
912
1087
|
getRandomDate,
|
|
913
1088
|
getRandomColour,
|
|
914
|
-
getRandomColour as getRandomColor,
|
|
915
1089
|
getRandomBoolean,
|
|
916
1090
|
getPosition,
|
|
917
1091
|
getNumber,
|
|
1092
|
+
getForegroundColour,
|
|
918
1093
|
getFocusableElements,
|
|
919
1094
|
getElementUnderPointer,
|
|
920
1095
|
findParentElement,
|
package/dist/js/index.mjs
CHANGED
package/dist/js/random.js
CHANGED
package/dist/js/random.mjs
CHANGED
package/package.json
CHANGED
package/src/js/colour.ts
ADDED
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import {clamp} from './number';
|
|
2
|
+
|
|
3
|
+
type Colour<Model> = {
|
|
4
|
+
/**
|
|
5
|
+
* The current value of the colour
|
|
6
|
+
*/
|
|
7
|
+
readonly value: Model;
|
|
8
|
+
/**
|
|
9
|
+
* Convert the colour to a hex-colour
|
|
10
|
+
*/
|
|
11
|
+
toHex(): HexColour;
|
|
12
|
+
/**
|
|
13
|
+
* Get the colour as a _CSS-formatted_ string
|
|
14
|
+
*/
|
|
15
|
+
toString(): string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type HexColour = {
|
|
19
|
+
/**
|
|
20
|
+
* The current value of the colour
|
|
21
|
+
*/
|
|
22
|
+
value: string;
|
|
23
|
+
/**
|
|
24
|
+
* Convert the colour to an RGB-colour
|
|
25
|
+
*/
|
|
26
|
+
toHsl(): HSLColour;
|
|
27
|
+
/**
|
|
28
|
+
* Convert the colour to an HSL-colour
|
|
29
|
+
*/
|
|
30
|
+
toRgb(): RGBColour;
|
|
31
|
+
/**
|
|
32
|
+
* Get the colour as a string
|
|
33
|
+
*/
|
|
34
|
+
toString(): string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type HSLColour = {
|
|
38
|
+
/**
|
|
39
|
+
* The current hue
|
|
40
|
+
*/
|
|
41
|
+
hue: number;
|
|
42
|
+
/**
|
|
43
|
+
* The current lightness
|
|
44
|
+
*/
|
|
45
|
+
lightness: number;
|
|
46
|
+
/**
|
|
47
|
+
* The current saturation
|
|
48
|
+
*/
|
|
49
|
+
saturation: number;
|
|
50
|
+
/**
|
|
51
|
+
* Convert the colour to an RGB-colour
|
|
52
|
+
*/
|
|
53
|
+
toRgb(): RGBColour;
|
|
54
|
+
} & Colour<HSLColourValue>;
|
|
55
|
+
|
|
56
|
+
export type HSLColourValue = {
|
|
57
|
+
hue: number;
|
|
58
|
+
lightness: number;
|
|
59
|
+
saturation: number;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type Property<Value> = {
|
|
63
|
+
get(): Value;
|
|
64
|
+
set(value: Value): void;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type RGBColour = {
|
|
68
|
+
/**
|
|
69
|
+
* The current blue value
|
|
70
|
+
*/
|
|
71
|
+
blue: number;
|
|
72
|
+
/**
|
|
73
|
+
* The current green value
|
|
74
|
+
*/
|
|
75
|
+
green: number;
|
|
76
|
+
/**
|
|
77
|
+
* The current red value
|
|
78
|
+
*/
|
|
79
|
+
red: number;
|
|
80
|
+
/**
|
|
81
|
+
* Convert the colour to an HSL-colour
|
|
82
|
+
*/
|
|
83
|
+
toHsl(): HSLColour;
|
|
84
|
+
} & Colour<RGBColourValue>;
|
|
85
|
+
|
|
86
|
+
export type RGBColourValue = {
|
|
87
|
+
blue: number;
|
|
88
|
+
green: number;
|
|
89
|
+
red: number;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const anyPattern = /^#*([a-f0-9]{3}){1,2}$/i;
|
|
93
|
+
const groupedPattern = /^#*([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i;
|
|
94
|
+
|
|
95
|
+
function createHex(original: string): HexColour {
|
|
96
|
+
let value = original.slice();
|
|
97
|
+
|
|
98
|
+
const instance = Object.create({
|
|
99
|
+
toHsl() {
|
|
100
|
+
return hexToRgb(value).toHsl();
|
|
101
|
+
},
|
|
102
|
+
toRgb() {
|
|
103
|
+
return hexToRgb(value);
|
|
104
|
+
},
|
|
105
|
+
toString() {
|
|
106
|
+
return value;
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
Object.defineProperty(instance, 'value', {
|
|
111
|
+
get() {
|
|
112
|
+
return value.slice();
|
|
113
|
+
},
|
|
114
|
+
set(hex: string) {
|
|
115
|
+
if (anyPattern.test(hex)) {
|
|
116
|
+
value = `#${getHex(hex)}`;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
return instance;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function createHsl(original: HSLColourValue): HSLColour {
|
|
125
|
+
const value = {...original};
|
|
126
|
+
|
|
127
|
+
const instance = Object.create({
|
|
128
|
+
toHex() {
|
|
129
|
+
return hslToRgb(value).toHex();
|
|
130
|
+
},
|
|
131
|
+
toRgb() {
|
|
132
|
+
return hslToRgb(value);
|
|
133
|
+
},
|
|
134
|
+
toString() {
|
|
135
|
+
return `hsl(${value.hue}, ${value.saturation}%, ${value.lightness}%)`;
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
Object.defineProperties(instance, {
|
|
140
|
+
hue: createProperty(value, 'hue', 0, 360),
|
|
141
|
+
lightness: createProperty(value, 'lightness', 0, 100),
|
|
142
|
+
saturation: createProperty(value, 'saturation', 0, 100),
|
|
143
|
+
value: {value},
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
return instance;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function createProperty(
|
|
150
|
+
store: Record<string, number>,
|
|
151
|
+
key: string,
|
|
152
|
+
min: number,
|
|
153
|
+
max: number,
|
|
154
|
+
): Property<number> {
|
|
155
|
+
return {
|
|
156
|
+
get() {
|
|
157
|
+
return store[key];
|
|
158
|
+
},
|
|
159
|
+
set(value) {
|
|
160
|
+
store[key] = clamp(value, min, max);
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function createRgb(original: RGBColourValue): RGBColour {
|
|
166
|
+
const value = {...original};
|
|
167
|
+
|
|
168
|
+
const instance = Object.create({
|
|
169
|
+
toHex() {
|
|
170
|
+
return rgbToHex(value);
|
|
171
|
+
},
|
|
172
|
+
toHsl() {
|
|
173
|
+
return rgbToHsl(value);
|
|
174
|
+
},
|
|
175
|
+
toString() {
|
|
176
|
+
return `rgb(${value.red}, ${value.green}, ${value.blue})`;
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
Object.defineProperties(instance, {
|
|
181
|
+
blue: createProperty(value, 'blue', 0, 255),
|
|
182
|
+
green: createProperty(value, 'green', 0, 255),
|
|
183
|
+
red: createProperty(value, 'red', 0, 255),
|
|
184
|
+
value: {value},
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
return instance;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get a foreground colour _(usually text)_ based on a background colour's luminance
|
|
192
|
+
*/
|
|
193
|
+
export function getForegroundColour(value: RGBColourValue): string {
|
|
194
|
+
const values = [value.blue / 255, value.green / 255, value.red / 255];
|
|
195
|
+
|
|
196
|
+
for (let colour of values) {
|
|
197
|
+
if (colour <= 0.03928) {
|
|
198
|
+
colour /= 12.92;
|
|
199
|
+
} else {
|
|
200
|
+
colour = ((colour + 0.055) / 1.055) ** 2.4;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const luminance =
|
|
205
|
+
0.2126 * values[2] + 0.7152 * values[1] + 0.0722 * values[0];
|
|
206
|
+
|
|
207
|
+
// Rudimentary and ureliable?; implement APCA for more reliable results?
|
|
208
|
+
return luminance > 0.625 ? 'black' : 'white';
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function getHex(value: string): string {
|
|
212
|
+
const normalised = value.replace(/^#/, '');
|
|
213
|
+
|
|
214
|
+
return normalised.length === 3
|
|
215
|
+
? normalised
|
|
216
|
+
.split('')
|
|
217
|
+
.map(character => character.repeat(2))
|
|
218
|
+
.join('')
|
|
219
|
+
: normalised;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Convert a hex-colour to an RGB-colour
|
|
224
|
+
*/
|
|
225
|
+
export function hexToRgb(value: string): RGBColour {
|
|
226
|
+
const hex = anyPattern.test(value) ? getHex(value) : '';
|
|
227
|
+
const pairs = groupedPattern.exec(hex) ?? [];
|
|
228
|
+
const rgb = [];
|
|
229
|
+
|
|
230
|
+
const {length} = pairs;
|
|
231
|
+
|
|
232
|
+
for (let index = 1; index < length; index += 1) {
|
|
233
|
+
rgb.push(Number.parseInt(pairs[index], 16));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return createRgb({blue: rgb[2] ?? 0, green: rgb[1] ?? 0, red: rgb[0] ?? 0});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* - Convert an HSL-colour to an RGB-colour
|
|
241
|
+
* - Thanks, https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js#L61
|
|
242
|
+
*/
|
|
243
|
+
export function hslToRgb(value: HSLColourValue): RGBColour {
|
|
244
|
+
let hue = value.hue % 360;
|
|
245
|
+
|
|
246
|
+
if (hue < 0) {
|
|
247
|
+
hue += 360;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const saturation = value.saturation / 100;
|
|
251
|
+
const lightness = value.lightness / 100;
|
|
252
|
+
|
|
253
|
+
function get(value: number) {
|
|
254
|
+
const part = (value + hue / 30) % 12;
|
|
255
|
+
const mod = saturation * Math.min(lightness, 1 - lightness);
|
|
256
|
+
|
|
257
|
+
return lightness - mod * Math.max(-1, Math.min(part - 3, 9 - part, 1));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return createRgb({
|
|
261
|
+
blue: clamp(Math.round(get(4) * 255), 0, 255),
|
|
262
|
+
green: clamp(Math.round(get(8) * 255), 0, 255),
|
|
263
|
+
red: clamp(Math.round(get(0) * 255), 0, 255),
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Convert an RGB-colour to a hex-colour
|
|
269
|
+
*/
|
|
270
|
+
export function rgbToHex(value: RGBColourValue): HexColour {
|
|
271
|
+
return createHex(
|
|
272
|
+
`#${[value.red, value.green, value.blue]
|
|
273
|
+
.map(colour => {
|
|
274
|
+
const hex = colour.toString(16);
|
|
275
|
+
|
|
276
|
+
return hex.length === 1 ? `0${hex}` : hex;
|
|
277
|
+
})
|
|
278
|
+
.join('')}`,
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* - Convert an RGB-colour to an HSL-colour
|
|
284
|
+
* - Thanks, https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js#L26
|
|
285
|
+
*/
|
|
286
|
+
export function rgbToHsl(rgb: RGBColourValue): HSLColour {
|
|
287
|
+
const blue = rgb.blue / 255;
|
|
288
|
+
const green = rgb.green / 255;
|
|
289
|
+
const red = rgb.red / 255;
|
|
290
|
+
|
|
291
|
+
const max = Math.max(blue, green, red);
|
|
292
|
+
const min = Math.min(blue, green, red);
|
|
293
|
+
|
|
294
|
+
const delta = max - min;
|
|
295
|
+
const lightness = (min + max) / 2;
|
|
296
|
+
|
|
297
|
+
let hue = 0;
|
|
298
|
+
let saturation = 0;
|
|
299
|
+
|
|
300
|
+
if (delta !== 0) {
|
|
301
|
+
saturation =
|
|
302
|
+
lightness === 0 || lightness === 1
|
|
303
|
+
? 0
|
|
304
|
+
: (max - lightness) / Math.min(lightness, 1 - lightness);
|
|
305
|
+
|
|
306
|
+
switch (max) {
|
|
307
|
+
case blue:
|
|
308
|
+
hue = (red - green) / delta + 4;
|
|
309
|
+
break;
|
|
310
|
+
case green:
|
|
311
|
+
hue = (blue - red) / delta + 2;
|
|
312
|
+
break;
|
|
313
|
+
case red:
|
|
314
|
+
hue = (green - blue) / delta + (green < blue ? 6 : 0);
|
|
315
|
+
break;
|
|
316
|
+
default:
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
hue *= 60;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (saturation < 0) {
|
|
324
|
+
hue += 180;
|
|
325
|
+
saturation = Math.abs(saturation);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (hue >= 360) {
|
|
329
|
+
hue -= 360;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return createHsl({
|
|
333
|
+
hue: +hue.toFixed(2),
|
|
334
|
+
lightness: +(lightness * 100).toFixed(2),
|
|
335
|
+
saturation: +(saturation * 100).toFixed(2),
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
|
package/src/js/index.ts
CHANGED
package/src/js/random.ts
CHANGED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
type Colour<Model> = {
|
|
2
|
+
/**
|
|
3
|
+
* The current value of the colour
|
|
4
|
+
*/
|
|
5
|
+
readonly value: Model;
|
|
6
|
+
/**
|
|
7
|
+
* Convert the colour to a hex-colour
|
|
8
|
+
*/
|
|
9
|
+
toHex(): HexColour;
|
|
10
|
+
/**
|
|
11
|
+
* Get the colour as a _CSS-formatted_ string
|
|
12
|
+
*/
|
|
13
|
+
toString(): string;
|
|
14
|
+
};
|
|
15
|
+
type HexColour = {
|
|
16
|
+
/**
|
|
17
|
+
* The current value of the colour
|
|
18
|
+
*/
|
|
19
|
+
value: string;
|
|
20
|
+
/**
|
|
21
|
+
* Convert the colour to an RGB-colour
|
|
22
|
+
*/
|
|
23
|
+
toHsl(): HSLColour;
|
|
24
|
+
/**
|
|
25
|
+
* Convert the colour to an HSL-colour
|
|
26
|
+
*/
|
|
27
|
+
toRgb(): RGBColour;
|
|
28
|
+
/**
|
|
29
|
+
* Get the colour as a string
|
|
30
|
+
*/
|
|
31
|
+
toString(): string;
|
|
32
|
+
};
|
|
33
|
+
export type HSLColour = {
|
|
34
|
+
/**
|
|
35
|
+
* The current hue
|
|
36
|
+
*/
|
|
37
|
+
hue: number;
|
|
38
|
+
/**
|
|
39
|
+
* The current lightness
|
|
40
|
+
*/
|
|
41
|
+
lightness: number;
|
|
42
|
+
/**
|
|
43
|
+
* The current saturation
|
|
44
|
+
*/
|
|
45
|
+
saturation: number;
|
|
46
|
+
/**
|
|
47
|
+
* Convert the colour to an RGB-colour
|
|
48
|
+
*/
|
|
49
|
+
toRgb(): RGBColour;
|
|
50
|
+
} & Colour<HSLColourValue>;
|
|
51
|
+
export type HSLColourValue = {
|
|
52
|
+
hue: number;
|
|
53
|
+
lightness: number;
|
|
54
|
+
saturation: number;
|
|
55
|
+
};
|
|
56
|
+
export type RGBColour = {
|
|
57
|
+
/**
|
|
58
|
+
* The current blue value
|
|
59
|
+
*/
|
|
60
|
+
blue: number;
|
|
61
|
+
/**
|
|
62
|
+
* The current green value
|
|
63
|
+
*/
|
|
64
|
+
green: number;
|
|
65
|
+
/**
|
|
66
|
+
* The current red value
|
|
67
|
+
*/
|
|
68
|
+
red: number;
|
|
69
|
+
/**
|
|
70
|
+
* Convert the colour to an HSL-colour
|
|
71
|
+
*/
|
|
72
|
+
toHsl(): HSLColour;
|
|
73
|
+
} & Colour<RGBColourValue>;
|
|
74
|
+
export type RGBColourValue = {
|
|
75
|
+
blue: number;
|
|
76
|
+
green: number;
|
|
77
|
+
red: number;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Get a foreground colour _(usually text)_ based on a background colour's luminance
|
|
81
|
+
*/
|
|
82
|
+
export declare function getForegroundColour(value: RGBColourValue): string;
|
|
83
|
+
/**
|
|
84
|
+
* Convert a hex-colour to an RGB-colour
|
|
85
|
+
*/
|
|
86
|
+
export declare function hexToRgb(value: string): RGBColour;
|
|
87
|
+
/**
|
|
88
|
+
* - Convert an HSL-colour to an RGB-colour
|
|
89
|
+
* - Thanks, https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js#L61
|
|
90
|
+
*/
|
|
91
|
+
export declare function hslToRgb(value: HSLColourValue): RGBColour;
|
|
92
|
+
/**
|
|
93
|
+
* Convert an RGB-colour to a hex-colour
|
|
94
|
+
*/
|
|
95
|
+
export declare function rgbToHex(value: RGBColourValue): HexColour;
|
|
96
|
+
/**
|
|
97
|
+
* - Convert an RGB-colour to an HSL-colour
|
|
98
|
+
* - Thanks, https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js#L26
|
|
99
|
+
*/
|
|
100
|
+
export declare function rgbToHsl(rgb: RGBColourValue): HSLColour;
|
|
101
|
+
export {};
|
package/types/index.d.ts
CHANGED
package/types/random.d.ts
CHANGED