@twin.org/image 0.0.2-next.9 → 0.0.3-next.2

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.
@@ -0,0 +1,213 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ /* eslint-disable no-bitwise */
4
+ import { GeneralError, Guards, Is } from "@twin.org/core";
5
+ /**
6
+ * Class to represent a color.
7
+ */
8
+ export class Color {
9
+ /**
10
+ * Runtime name for the class.
11
+ */
12
+ static CLASS_NAME = "Color";
13
+ /**
14
+ * @internal
15
+ */
16
+ _alpha;
17
+ /**
18
+ * @internal
19
+ */
20
+ _red;
21
+ /**
22
+ * @internal
23
+ */
24
+ _green;
25
+ /**
26
+ * @internal
27
+ */
28
+ _blue;
29
+ /**
30
+ * Create a new instance of color.
31
+ * @param alpha The alpha element of the color.
32
+ * @param red The red element of the color.
33
+ * @param green The green element of the color.
34
+ * @param blue The blue element of the color.
35
+ */
36
+ constructor(alpha, red, green, blue) {
37
+ Guards.number(Color.CLASS_NAME, "alpha", alpha);
38
+ Guards.number(Color.CLASS_NAME, "red", red);
39
+ Guards.number(Color.CLASS_NAME, "green", green);
40
+ Guards.number(Color.CLASS_NAME, "blue", blue);
41
+ if (alpha < 0 || alpha > 255) {
42
+ throw new GeneralError(Color.CLASS_NAME, "range", {
43
+ prop: "alpha",
44
+ value: alpha
45
+ });
46
+ }
47
+ if (red < 0 || red > 255) {
48
+ throw new GeneralError(Color.CLASS_NAME, "range", {
49
+ prop: "red",
50
+ value: red
51
+ });
52
+ }
53
+ if (green < 0 || green > 255) {
54
+ throw new GeneralError(Color.CLASS_NAME, "range", {
55
+ prop: "green",
56
+ value: green
57
+ });
58
+ }
59
+ if (blue < 0 || blue > 255) {
60
+ throw new GeneralError(Color.CLASS_NAME, "range", {
61
+ prop: "blue",
62
+ value: blue
63
+ });
64
+ }
65
+ this._alpha = alpha;
66
+ this._red = red;
67
+ this._green = green;
68
+ this._blue = blue;
69
+ }
70
+ /**
71
+ * Construct a color from a hex string.
72
+ * @param hex The hex string to parse.
73
+ * @returns The color.
74
+ * @throws Error if the format is incorrect.
75
+ */
76
+ static fromHex(hex) {
77
+ Guards.stringValue(Color.CLASS_NAME, "hex", hex);
78
+ let alpha;
79
+ let red;
80
+ let green;
81
+ let blue;
82
+ if (/^#[\dA-Fa-f]{3}$/.test(hex)) {
83
+ // #RGB
84
+ alpha = "0xFF";
85
+ red = hex.slice(1, 2).repeat(2);
86
+ green = hex.slice(2, 3).repeat(2);
87
+ blue = hex.slice(3, 4).repeat(2);
88
+ }
89
+ else if (/^#[\dA-Fa-f]{4}$/.test(hex)) {
90
+ // #ARGB
91
+ alpha = hex.slice(1, 2).repeat(2);
92
+ red = hex.slice(2, 3).repeat(2);
93
+ green = hex.slice(3, 4).repeat(2);
94
+ blue = hex.slice(4, 5).repeat(2);
95
+ }
96
+ else if (/^#[\dA-Fa-f]{6}$/.test(hex)) {
97
+ // #RRGGBB
98
+ alpha = "0xFF";
99
+ red = hex.slice(1, 3);
100
+ green = hex.slice(3, 5);
101
+ blue = hex.slice(5, 7);
102
+ }
103
+ else if (/^#[\dA-Fa-f]{8}$/.test(hex)) {
104
+ // #AARRGGBB
105
+ alpha = hex.slice(1, 3);
106
+ red = hex.slice(3, 5);
107
+ green = hex.slice(5, 7);
108
+ blue = hex.slice(7, 9);
109
+ }
110
+ else {
111
+ throw new GeneralError(Color.CLASS_NAME, "hex", { hex });
112
+ }
113
+ return new Color(Number.parseInt(alpha, 16), Number.parseInt(red, 16), Number.parseInt(green, 16), Number.parseInt(blue, 16));
114
+ }
115
+ /**
116
+ * Coerce an unknown type to a color.
117
+ * @param value The value to try and convert.
118
+ * @returns The color if one can be created.
119
+ */
120
+ static coerce(value) {
121
+ if (Is.object(value) &&
122
+ Is.number(value._alpha) &&
123
+ Is.number(value._red) &&
124
+ Is.number(value._green) &&
125
+ Is.number(value._blue)) {
126
+ return new Color(value._alpha, value._red, value._green, value._blue);
127
+ }
128
+ else if (Is.stringValue(value) && value.startsWith("#")) {
129
+ try {
130
+ return Color.fromHex(value);
131
+ }
132
+ catch { }
133
+ }
134
+ }
135
+ /**
136
+ * Get the alpha element.
137
+ * @returns The alpha element.
138
+ */
139
+ alpha() {
140
+ return this._alpha;
141
+ }
142
+ /**
143
+ * Get the red element.
144
+ * @returns The red element.
145
+ */
146
+ red() {
147
+ return this._red;
148
+ }
149
+ /**
150
+ * Get the green element.
151
+ * @returns The green element.
152
+ */
153
+ green() {
154
+ return this._green;
155
+ }
156
+ /**
157
+ * Get the blue element.
158
+ * @returns The blue element.
159
+ */
160
+ blue() {
161
+ return this._blue;
162
+ }
163
+ /**
164
+ * Get color as argb.
165
+ * @returns The color as argb.
166
+ */
167
+ argb() {
168
+ return ((this._alpha << 24) | (this._red << 16) | (this._green << 8) | this._blue) >>> 0;
169
+ }
170
+ /**
171
+ * Get color as rgba.
172
+ * @returns The color as rgba.
173
+ */
174
+ rgba() {
175
+ return ((this._red << 24) | (this._green << 16) | (this._blue << 8) | this._alpha) >>> 0;
176
+ }
177
+ /**
178
+ * Get color as rgb text.
179
+ * @returns The color as rgb.
180
+ */
181
+ rgbText() {
182
+ return `rgb(${this._red},${this._green},${this._blue})`;
183
+ }
184
+ /**
185
+ * Get color as rgba text.
186
+ * @returns The color as rgba.
187
+ */
188
+ rgbaText() {
189
+ return `rgba(${this._red},${this._green},${this._blue},${Math.round((this._alpha / 255) * 100) / 100})`;
190
+ }
191
+ /**
192
+ * Get color as hex no alpha.
193
+ * @returns The color as hex with no alpha component.
194
+ */
195
+ hex() {
196
+ const red = `00${this._red.toString(16)}`.slice(-2);
197
+ const green = `00${this._green.toString(16)}`.slice(-2);
198
+ const blue = `00${this._blue.toString(16)}`.slice(-2);
199
+ return `#${red}${green}${blue}`.toUpperCase();
200
+ }
201
+ /**
202
+ * Get color as hex with alpha.
203
+ * @returns The color as hex with with alpha component.
204
+ */
205
+ hexWithAlpha() {
206
+ const alpha = `00${this._alpha.toString(16)}`.slice(-2);
207
+ const red = `00${this._red.toString(16)}`.slice(-2);
208
+ const green = `00${this._green.toString(16)}`.slice(-2);
209
+ const blue = `00${this._blue.toString(16)}`.slice(-2);
210
+ return `#${alpha}${red}${green}${blue}`.toUpperCase();
211
+ }
212
+ }
213
+ //# sourceMappingURL=color.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/color.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n/* eslint-disable no-bitwise */\n\nimport { GeneralError, Guards, Is } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\n\n/**\n * Class to represent a color.\n */\nexport class Color {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Color>();\n\n\t/**\n\t * @internal\n\t */\n\tprivate readonly _alpha: number;\n\n\t/**\n\t * @internal\n\t */\n\tprivate readonly _red: number;\n\n\t/**\n\t * @internal\n\t */\n\tprivate readonly _green: number;\n\n\t/**\n\t * @internal\n\t */\n\tprivate readonly _blue: number;\n\n\t/**\n\t * Create a new instance of color.\n\t * @param alpha The alpha element of the color.\n\t * @param red The red element of the color.\n\t * @param green The green element of the color.\n\t * @param blue The blue element of the color.\n\t */\n\tconstructor(alpha: number, red: number, green: number, blue: number) {\n\t\tGuards.number(Color.CLASS_NAME, nameof(alpha), alpha);\n\t\tGuards.number(Color.CLASS_NAME, nameof(red), red);\n\t\tGuards.number(Color.CLASS_NAME, nameof(green), green);\n\t\tGuards.number(Color.CLASS_NAME, nameof(blue), blue);\n\n\t\tif (alpha < 0 || alpha > 255) {\n\t\t\tthrow new GeneralError(Color.CLASS_NAME, \"range\", {\n\t\t\t\tprop: nameof(alpha),\n\t\t\t\tvalue: alpha\n\t\t\t});\n\t\t}\n\t\tif (red < 0 || red > 255) {\n\t\t\tthrow new GeneralError(Color.CLASS_NAME, \"range\", {\n\t\t\t\tprop: nameof(red),\n\t\t\t\tvalue: red\n\t\t\t});\n\t\t}\n\t\tif (green < 0 || green > 255) {\n\t\t\tthrow new GeneralError(Color.CLASS_NAME, \"range\", {\n\t\t\t\tprop: nameof(green),\n\t\t\t\tvalue: green\n\t\t\t});\n\t\t}\n\t\tif (blue < 0 || blue > 255) {\n\t\t\tthrow new GeneralError(Color.CLASS_NAME, \"range\", {\n\t\t\t\tprop: nameof(blue),\n\t\t\t\tvalue: blue\n\t\t\t});\n\t\t}\n\n\t\tthis._alpha = alpha;\n\t\tthis._red = red;\n\t\tthis._green = green;\n\t\tthis._blue = blue;\n\t}\n\n\t/**\n\t * Construct a color from a hex string.\n\t * @param hex The hex string to parse.\n\t * @returns The color.\n\t * @throws Error if the format is incorrect.\n\t */\n\tpublic static fromHex(hex: string): Color {\n\t\tGuards.stringValue(Color.CLASS_NAME, nameof(hex), hex);\n\n\t\tlet alpha;\n\t\tlet red;\n\t\tlet green;\n\t\tlet blue;\n\t\tif (/^#[\\dA-Fa-f]{3}$/.test(hex)) {\n\t\t\t// #RGB\n\t\t\talpha = \"0xFF\";\n\t\t\tred = hex.slice(1, 2).repeat(2);\n\t\t\tgreen = hex.slice(2, 3).repeat(2);\n\t\t\tblue = hex.slice(3, 4).repeat(2);\n\t\t} else if (/^#[\\dA-Fa-f]{4}$/.test(hex)) {\n\t\t\t// #ARGB\n\t\t\talpha = hex.slice(1, 2).repeat(2);\n\t\t\tred = hex.slice(2, 3).repeat(2);\n\t\t\tgreen = hex.slice(3, 4).repeat(2);\n\t\t\tblue = hex.slice(4, 5).repeat(2);\n\t\t} else if (/^#[\\dA-Fa-f]{6}$/.test(hex)) {\n\t\t\t// #RRGGBB\n\t\t\talpha = \"0xFF\";\n\t\t\tred = hex.slice(1, 3);\n\t\t\tgreen = hex.slice(3, 5);\n\t\t\tblue = hex.slice(5, 7);\n\t\t} else if (/^#[\\dA-Fa-f]{8}$/.test(hex)) {\n\t\t\t// #AARRGGBB\n\t\t\talpha = hex.slice(1, 3);\n\t\t\tred = hex.slice(3, 5);\n\t\t\tgreen = hex.slice(5, 7);\n\t\t\tblue = hex.slice(7, 9);\n\t\t} else {\n\t\t\tthrow new GeneralError(Color.CLASS_NAME, \"hex\", { hex });\n\t\t}\n\t\treturn new Color(\n\t\t\tNumber.parseInt(alpha, 16),\n\t\t\tNumber.parseInt(red, 16),\n\t\t\tNumber.parseInt(green, 16),\n\t\t\tNumber.parseInt(blue, 16)\n\t\t);\n\t}\n\n\t/**\n\t * Coerce an unknown type to a color.\n\t * @param value The value to try and convert.\n\t * @returns The color if one can be created.\n\t */\n\tpublic static coerce(value: unknown): Color | undefined {\n\t\tif (\n\t\t\tIs.object<Color>(value) &&\n\t\t\tIs.number(value._alpha) &&\n\t\t\tIs.number(value._red) &&\n\t\t\tIs.number(value._green) &&\n\t\t\tIs.number(value._blue)\n\t\t) {\n\t\t\treturn new Color(value._alpha, value._red, value._green, value._blue);\n\t\t} else if (Is.stringValue(value) && value.startsWith(\"#\")) {\n\t\t\ttry {\n\t\t\t\treturn Color.fromHex(value);\n\t\t\t} catch {}\n\t\t}\n\t}\n\n\t/**\n\t * Get the alpha element.\n\t * @returns The alpha element.\n\t */\n\tpublic alpha(): number {\n\t\treturn this._alpha;\n\t}\n\n\t/**\n\t * Get the red element.\n\t * @returns The red element.\n\t */\n\tpublic red(): number {\n\t\treturn this._red;\n\t}\n\n\t/**\n\t * Get the green element.\n\t * @returns The green element.\n\t */\n\tpublic green(): number {\n\t\treturn this._green;\n\t}\n\n\t/**\n\t * Get the blue element.\n\t * @returns The blue element.\n\t */\n\tpublic blue(): number {\n\t\treturn this._blue;\n\t}\n\n\t/**\n\t * Get color as argb.\n\t * @returns The color as argb.\n\t */\n\tpublic argb(): number {\n\t\treturn ((this._alpha << 24) | (this._red << 16) | (this._green << 8) | this._blue) >>> 0;\n\t}\n\n\t/**\n\t * Get color as rgba.\n\t * @returns The color as rgba.\n\t */\n\tpublic rgba(): number {\n\t\treturn ((this._red << 24) | (this._green << 16) | (this._blue << 8) | this._alpha) >>> 0;\n\t}\n\n\t/**\n\t * Get color as rgb text.\n\t * @returns The color as rgb.\n\t */\n\tpublic rgbText(): string {\n\t\treturn `rgb(${this._red},${this._green},${this._blue})`;\n\t}\n\n\t/**\n\t * Get color as rgba text.\n\t * @returns The color as rgba.\n\t */\n\tpublic rgbaText(): string {\n\t\treturn `rgba(${this._red},${this._green},${this._blue},${Math.round((this._alpha / 255) * 100) / 100})`;\n\t}\n\n\t/**\n\t * Get color as hex no alpha.\n\t * @returns The color as hex with no alpha component.\n\t */\n\tpublic hex(): string {\n\t\tconst red = `00${this._red.toString(16)}`.slice(-2);\n\t\tconst green = `00${this._green.toString(16)}`.slice(-2);\n\t\tconst blue = `00${this._blue.toString(16)}`.slice(-2);\n\t\treturn `#${red}${green}${blue}`.toUpperCase();\n\t}\n\n\t/**\n\t * Get color as hex with alpha.\n\t * @returns The color as hex with with alpha component.\n\t */\n\tpublic hexWithAlpha(): string {\n\t\tconst alpha = `00${this._alpha.toString(16)}`.slice(-2);\n\t\tconst red = `00${this._red.toString(16)}`.slice(-2);\n\t\tconst green = `00${this._green.toString(16)}`.slice(-2);\n\t\tconst blue = `00${this._blue.toString(16)}`.slice(-2);\n\t\treturn `#${alpha}${red}${green}${blue}`.toUpperCase();\n\t}\n}\n"]}