@retrovm/color 0.1.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.
Files changed (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +92 -0
  3. package/package.json +32 -0
  4. package/src/color.ts +589 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Juan Carlos González Amestoy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # @retrovm/color
2
+
3
+ Immutable and mutable RGB color classes with HSV conversion, ANSI terminal output, and a full set of named CSS colors.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ bun add @retrovm/color
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { Color, MutableColor } from "@retrovm/color"
15
+
16
+ // From hex string
17
+ const red = new Color("#ff0000")
18
+
19
+ // From RGB components (0.0 – 1.0)
20
+ const green = new Color(0, 1, 0, 1)
21
+
22
+ // Named colors
23
+ const blue = Color.blue
24
+ const white = Color.white
25
+
26
+ // From HSV
27
+ const hsvColor = Color.fromHSV(0.6, 0.8, 1.0)
28
+
29
+ // Operations (return new Color)
30
+ const mixed = red.interpolate(blue, 0.5)
31
+ const brighter = red.mul(1.2)
32
+
33
+ // ANSI terminal output
34
+ console.log(red.toAnsiRGB() + "Hello" + "\x1b[0m")
35
+ console.log(red.toAnsiBackgroundRGB() + "Hello" + "\x1b[0m")
36
+
37
+ // Convert to hex string
38
+ console.log(red.toString()) // "#ff0000ff"
39
+ ```
40
+
41
+ ## MutableColor
42
+
43
+ `MutableColor` extends `Color` with setters and in-place operations:
44
+
45
+ ```ts
46
+ const c = new MutableColor(1, 0, 0)
47
+ c.r = 0.5
48
+ c.addIn(Color.blue)
49
+ c.mulIn(0.8)
50
+ c.interpolateIn(Color.white, 0.2)
51
+ ```
52
+
53
+ ## API
54
+
55
+ ### `new Color(hex: string)`
56
+ ### `new Color(r, g, b, a?)`
57
+
58
+ Components are in the `0.0 – 1.0` range.
59
+
60
+ ### Properties (read-only on `Color`)
61
+
62
+ | Property | Description |
63
+ |----------|-------------|
64
+ | `r, g, b, a` | RGBA components |
65
+ | `h, s, v` | HSV components (computed lazily) |
66
+
67
+ ### Methods
68
+
69
+ | Method | Description |
70
+ |--------|-------------|
71
+ | `add(c)` | Add two colors |
72
+ | `sub(c)` | Subtract two colors |
73
+ | `mul(n)` | Multiply by scalar |
74
+ | `div(n)` | Divide by scalar |
75
+ | `interpolate(c, t)` | Interpolate toward `c` by factor `t` |
76
+ | `interpolateIn(c, t)` | Interpolate in place |
77
+ | `toAnsiRGB()` | ANSI foreground escape sequence |
78
+ | `toAnsiBackgroundRGB()` | ANSI background escape sequence |
79
+ | `toString()` | Hex string `#rrggbbaa` |
80
+
81
+ ### Static
82
+
83
+ | | Description |
84
+ |-|-------------|
85
+ | `Color.fromHSV(h, s, v, a?)` | Construct from HSV |
86
+ | `Color.names` | Array of all named color names |
87
+ | `Color.colors` | Object map of all named colors |
88
+ | `Color.red`, `Color.blue`, … | 140+ named CSS colors |
89
+
90
+ ## License
91
+
92
+ MIT
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@retrovm/color",
3
+ "version": "0.1.0",
4
+ "description": "Immutable and mutable RGB color classes with HSV, ANSI, and named color support",
5
+ "author": "Juan Carlos González Amestoy",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "module": "src/color.ts",
9
+ "exports": {
10
+ ".": "./src/color.ts"
11
+ },
12
+ "files": [
13
+ "src",
14
+ "LICENSE"
15
+ ],
16
+ "keywords": [
17
+ "color",
18
+ "rgb",
19
+ "hsv",
20
+ "ansi",
21
+ "terminal"
22
+ ],
23
+ "devDependencies": {
24
+ "@types/bun": "latest"
25
+ },
26
+ "peerDependencies": {
27
+ "typescript": "^5"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ }
32
+ }
package/src/color.ts ADDED
@@ -0,0 +1,589 @@
1
+ /*Copyright (c) 2026 Juan Carlos González Amestoy
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.*/
20
+
21
+ let _colors: { [key: string]: Color } | undefined
22
+
23
+ const fract = (x: number): number => {
24
+ return x - Math.floor(x)
25
+ }
26
+
27
+ const interpolate = (a: number, b: number, t: number): number => {
28
+ return a + (b - a) * t
29
+ }
30
+
31
+ const clamp = (x: number, min: number=0, max: number=1): number => {
32
+ const c = x > min ? x : min
33
+ return max < c ? max : c
34
+ }
35
+
36
+ export class Color {
37
+ protected _r: number
38
+ protected _g: number
39
+ protected _b: number
40
+ protected _a: number
41
+
42
+ protected _h: number | undefined
43
+ protected _s: number | undefined
44
+ protected _v: number | undefined
45
+
46
+ // Cached ANSI escape sequences. Populated lazily by toAnsiRGB() and
47
+ // toAnsiBackgroundRGB() and reset to undefined by any code that mutates
48
+ // _r/_g/_b (see interpolateIn here, and the setters/*In methods in
49
+ // MutableColor). For the static readonly named colors these are computed
50
+ // once per process and reused forever.
51
+ protected _ansiFg: string | undefined
52
+ protected _ansiBg: string | undefined
53
+
54
+ /**
55
+ * Construct a color from a string or RGB components
56
+ * @param s A color string in the format #RRGGBB
57
+ */
58
+ constructor(s: string)
59
+
60
+ /**
61
+ * Construct a color from RGB components
62
+ * @param r The red component
63
+ * @param g The green component
64
+ * @param b The blue component
65
+ * @param a The alpha component defaults to 1.0
66
+ */
67
+ constructor(r: number, g: number, b: number, a: number)
68
+ constructor(r: number, g: number, b: number)
69
+
70
+ constructor(rs: number | string, g?: number, b?: number, a: number = 1.0) {
71
+ if (typeof rs === 'number' && g !== undefined && b !== undefined) {
72
+ this._r = rs
73
+ this._g = g
74
+ this._b = b
75
+ this._a = a
76
+ } else if (typeof rs === 'string') {
77
+ const match = rs.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i)
78
+
79
+ if (match) {
80
+ this._r = parseInt(match[1]!, 16) / 255
81
+ this._g = parseInt(match[2]!, 16) / 255
82
+ this._b = parseInt(match[3]!, 16) / 255
83
+ this._a = match[4] ? parseInt(match[4], 16) / 255 : 1.0
84
+ } else {
85
+ const match = rs.match(/^#?([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])?$/i)
86
+
87
+ if (match) {
88
+ this._r = parseInt(match[1]!, 16) / 15
89
+ this._g = parseInt(match[2]!, 16) / 15
90
+ this._b = parseInt(match[3]!, 16) / 15
91
+ this._a = match[4] ? parseInt(match[4], 16) / 15 : 1.0
92
+ } else {
93
+ throw new Error('Invalid color string')
94
+ }
95
+ }
96
+ } else {
97
+ throw new Error('Invalid arguments')
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Get the red component
103
+ * @returns {number}
104
+ * @readonly
105
+ */
106
+ get r() {
107
+ return this._r
108
+ }
109
+
110
+ /**
111
+ * Get the green component
112
+ * @returns {number}
113
+ * @readonly
114
+ */
115
+ get g() {
116
+ return this._g
117
+ }
118
+
119
+ /**
120
+ * Get the blue component
121
+ * @returns {number}
122
+ * @readonly
123
+ */
124
+ get b() {
125
+ return this._b
126
+ }
127
+
128
+ /**
129
+ * Get the alpha component
130
+ * @returns {number}
131
+ * @readonly
132
+ */
133
+ get a() {
134
+ return this._a
135
+ }
136
+
137
+ /**
138
+ * Get the hue component
139
+ * @returns {number}
140
+ * @readonly
141
+ */
142
+ get h() {
143
+ if (this._h === undefined) {
144
+ const M = Math.max(this._r, this._g, this._b)
145
+ const m = Math.min(this._r, this._g, this._b)
146
+ const c = M - m
147
+
148
+ if (c === 0) {
149
+ this._h = 0
150
+ } else if (M === this._r) {
151
+ this._h = ((this._g - this._b) / c) % 6
152
+ } else if (M === this._g) {
153
+ this._h = (this._b - this._r) / c + 2
154
+ } else {
155
+ this._h = (this._r - this._g) / c + 4
156
+ }
157
+
158
+ this._h *= 60
159
+
160
+ if (this._h < 0) {
161
+ this._h += 360
162
+ }
163
+ }
164
+
165
+ return this._h / 360
166
+ }
167
+
168
+ /**
169
+ * Get the saturation component
170
+ * @returns {number}
171
+ * @readonly
172
+ */
173
+ get s() {
174
+ if (this._s === undefined) {
175
+ const M = Math.max(this._r, this._g, this._b)
176
+ const m = Math.min(this._r, this._g, this._b)
177
+ this._s = M !== 0 ? (M - m) / M : 0
178
+ }
179
+
180
+ return this._s
181
+ }
182
+
183
+ /**
184
+ * Get the value component
185
+ * @returns {number}
186
+ * @readonly
187
+ */
188
+ get v() {
189
+ if (this._v === undefined) {
190
+ this._v = Math.max(this._r, this._g, this._b)
191
+ }
192
+
193
+ return this._v
194
+ }
195
+
196
+ /**
197
+ * Add two colors together and return a new color
198
+ * @param {Color} c color to add
199
+ * @returns {Color}
200
+ */
201
+ add(c: Color): Color {
202
+ return new Color(this._r + c._r, this._g + c._g, this._b + c._b, this._a + c._a)
203
+ }
204
+
205
+ /**
206
+ * Subtract two colors and return a new color
207
+ * @param {Color} c Color to subtract
208
+ * @returns {Color}
209
+ */
210
+ sub(c: Color): Color {
211
+ return new Color(this._r - c._r, this._g - c._g, this._b - c._b, this._a - c._a)
212
+ }
213
+
214
+ /**
215
+ * Multiply a color by a scalar and return a new color
216
+ * @param {number} n Scalar to multiply
217
+ * @returns {Color}
218
+ */
219
+ mul(n: number): Color {
220
+ return new Color(this._r * n, this._g * n, this._b * n, this._a * n)
221
+ }
222
+
223
+ /**
224
+ * Divide a color by a scalar and return a new color
225
+ * @param {number} n Scalar to divide
226
+ * @returns {Color}
227
+ */
228
+ div(n: number): Color {
229
+ return new Color(this._r / n, this._g / n, this._b / n, this._a / n)
230
+ }
231
+
232
+ /**
233
+ * Interpolate between two colors and return a new color
234
+ * @param {Color} c Color to interpolate to
235
+ * @param {number} t Interpolation factor
236
+ * @returns {Color}
237
+ */
238
+ interpolate(c: Color, t: number): Color {
239
+ return new Color(this._r + (c._r - this._r) * t, this._g + (c._g - this._g) * t, this._b + (c._b - this._b) * t, this._a + (c._a - this._a) * t)
240
+ }
241
+
242
+ /**
243
+ * Interpolate between two colors and modify the current color
244
+ * @param {Color} c Color to interpolate to
245
+ * @param {number} t Interpolation factor
246
+ * @returns {Color}
247
+ */
248
+ interpolateIn(c: Color, t: number): Color {
249
+ this._r += (c._r - this._r) * t
250
+ this._g += (c._g - this._g) * t
251
+ this._b += (c._b - this._b) * t
252
+ this._a += (c._a - this._a) * t
253
+ this._invalidateCaches()
254
+ return this
255
+ }
256
+
257
+ /**
258
+ * Clears all derived caches (HSV and ANSI). Must be called by any code
259
+ * that mutates _r/_g/_b/_a after construction.
260
+ */
261
+ protected _invalidateCaches(): void {
262
+ this._h = undefined
263
+ this._s = undefined
264
+ this._v = undefined
265
+ this._ansiFg = undefined
266
+ this._ansiBg = undefined
267
+ }
268
+
269
+ /**
270
+ * Return a string representation of the color
271
+ * @returns {string}
272
+ */
273
+ toString() {
274
+ return `#${Math.round(this._r * 255)
275
+ .toString(16)
276
+ .padStart(2, '0')}${Math.round(this._g * 255)
277
+ .toString(16)
278
+ .padStart(2, '0')}${Math.round(this._b * 255)
279
+ .toString(16)
280
+ .padStart(2, '0')}${Math.round(this._a * 255)
281
+ .toString(16)
282
+ .padStart(2, '0')}`
283
+ }
284
+
285
+ /**
286
+ * Converts the current color to an ANSI escape sequence for styling text color in the terminal.
287
+ * @returns {string} The ANSI escape sequence representing the RGB color of the text.
288
+ */
289
+ toAnsiRGB() {
290
+ return this._ansiFg ??= `\x1b[38;2;${Math.floor(this._r * 255)};${Math.floor(this._g * 255)};${Math.floor(this._b * 255)}m`
291
+ }
292
+
293
+ /**
294
+ * Converts the current color to an ANSI escape sequence for styling background color of the text in the terminal.
295
+ * @returns {string} The ANSI escape sequence representing the RGB color of the text background.
296
+ */
297
+ toAnsiBackgroundRGB() {
298
+ return this._ansiBg ??= `\x1b[48;2;${Math.floor(this._r * 255)};${Math.floor(this._g * 255)};${Math.floor(this._b * 255)}m`
299
+ }
300
+
301
+ //Static methods
302
+
303
+ /**
304
+ * Create a color from hue, saturation, and value
305
+ * @param {number} h Hue
306
+ * @param {number} s Saturation
307
+ * @param {number} v Value
308
+ * @param {number} a Alpha defaults to 1.0
309
+ * @returns {Color}
310
+ */
311
+ static fromHSV(h: number, s: number, v: number, a: number = 1.0): Color {
312
+ let r = h + 1
313
+ let g = h + 2 / 3
314
+ let b = h + 1 / 3
315
+
316
+ r = Math.abs(fract(r) * 6 - 3)
317
+ g = Math.abs(fract(g) * 6 - 3)
318
+ b = Math.abs(fract(b) * 6 - 3)
319
+
320
+ r = v * interpolate(1, clamp(r - 1), s)
321
+ g = v * interpolate(1, clamp(g - 1), s)
322
+ b = v * interpolate(1, clamp(b - 1), s)
323
+
324
+ r = Math.round(r * 10000) / 10000
325
+ g = Math.round(g * 10000) / 10000
326
+ b = Math.round(b * 10000) / 10000
327
+
328
+ return new Color(r, g, b, a)
329
+ }
330
+
331
+ // #region Named colors
332
+ static readonly aliceBlue = new Color(0.941176, 0.972549, 1.0, 1.0)
333
+ static readonly antiqueWhite = new Color(0.980392, 0.921569, 0.843137, 1.0)
334
+ static readonly aqua = new Color(0.0, 1.0, 1.0, 1.0)
335
+ static readonly aquamarine = new Color(0.498039, 1.0, 0.831373, 1.0)
336
+ static readonly azure = new Color(0.941176, 1.0, 1.0, 1.0)
337
+ static readonly beige = new Color(0.960784, 0.960784, 0.862745, 1.0)
338
+ static readonly bisque = new Color(1.0, 0.894118, 0.768627, 1.0)
339
+ static readonly black = new Color(0.0, 0.0, 0.0, 1.0)
340
+ static readonly blanchedAlmond = new Color(1.0, 0.921569, 0.803922, 1.0)
341
+ static readonly blue = new Color(0.0, 0.0, 1.0, 1.0)
342
+ static readonly blueViolet = new Color(0.541176, 0.168627, 0.886275, 1.0)
343
+ static readonly brown = new Color(0.647059, 0.164706, 0.164706, 1.0)
344
+ static readonly burlyWood = new Color(0.870588, 0.721569, 0.529412, 1.0)
345
+ static readonly cadetBlue = new Color(0.372549, 0.619608, 0.627451, 1.0)
346
+ static readonly chartreuse = new Color(0.498039, 1.0, 0.0, 1.0)
347
+ static readonly chocolate = new Color(0.823529, 0.411765, 0.117647, 1.0)
348
+ static readonly coral = new Color(1.0, 0.498039, 0.313725, 1.0)
349
+ static readonly cornflowerBlue = new Color(0.392157, 0.584314, 0.929412, 1.0)
350
+ static readonly cornsilk = new Color(0.882353, 0.972549, 0.862745, 1.0)
351
+ static readonly crimson = new Color(0.862745, 0.078431, 0.235294, 1.0)
352
+ static readonly cyan = new Color(0.0, 1.0, 1.0, 1.0)
353
+ static readonly darkBlue = new Color(0.0, 0.0, 0.545098, 1.0)
354
+ static readonly darkCyan = new Color(0.0, 0.545098, 0.545098, 1.0)
355
+ static readonly darkGoldenrod = new Color(0.721569, 0.52549, 0.043137, 1.0)
356
+ static readonly darkGray = new Color(0.662745, 0.662745, 0.662745, 1.0)
357
+ static readonly darkGreen = new Color(0.0, 0.392157, 0.0, 1.0)
358
+ static readonly darkKhaki = new Color(0.741176, 0.717647, 0.419608, 1.0)
359
+ static readonly darkMagenta = new Color(0.545098, 0.0, 0.545098, 1.0)
360
+ static readonly darkOliveGreen = new Color(0.333333, 0.419608, 0.184314, 1.0)
361
+ static readonly darkOrange = new Color(1.0, 0.54902, 0.0, 1.0)
362
+ static readonly darkOrchid = new Color(0.6, 0.196078, 0.8, 1.0)
363
+ static readonly darkRed = new Color(0.545098, 0.0, 0.0, 1.0)
364
+ static readonly darkSalmon = new Color(0.913725, 0.588235, 0.478431, 1.0)
365
+ static readonly darkSeaGreen = new Color(0.560784, 0.737255, 0.560784, 1.0)
366
+ static readonly darkSlateBlue = new Color(0.282353, 0.239216, 0.545098, 1.0)
367
+ static readonly darkSlateGray = new Color(0.184314, 0.309804, 0.309804, 1.0)
368
+ static readonly darkTurquoise = new Color(0.0, 0.807843, 0.819608, 1.0)
369
+ static readonly darkViolet = new Color(0.580392, 0.0, 0.827451, 1.0)
370
+ static readonly deepPink = new Color(1.0, 0.078431, 0.576471, 1.0)
371
+ static readonly deepSkyBlue = new Color(0.0, 0.74902, 1.0, 1.0)
372
+ static readonly dimGray = new Color(0.411765, 0.411765, 0.411765, 1.0)
373
+ static readonly dodgerBlue = new Color(0.117647, 0.564706, 1.0, 1.0)
374
+ static readonly fireBrick = new Color(0.698039, 0.133333, 0.133333, 1.0)
375
+ static readonly floralWhite = new Color(1.0, 0.980392, 0.941176, 1.0)
376
+ static readonly forestGreen = new Color(0.133333, 0.545098, 0.133333, 1.0)
377
+ static readonly fuchsia = new Color(1.0, 0.0, 1.0, 1.0)
378
+ static readonly gainsboro = new Color(0.862745, 0.862745, 0.862745, 1.0)
379
+ static readonly ghostWhite = new Color(0.972549, 0.972549, 1.0, 1.0)
380
+ static readonly gold = new Color(1.0, 0.843137, 0.0, 1.0)
381
+ static readonly goldenrod = new Color(0.854902, 0.647059, 0.12549, 1.0)
382
+ static readonly gray = new Color(0.501961, 0.501961, 0.501961, 1.0)
383
+ static readonly green = new Color(0.0, 0.501961, 0.0, 1.0)
384
+ static readonly greenYellow = new Color(0.678431, 1.0, 0.184314, 1.0)
385
+ static readonly honeydew = new Color(0.941176, 1.0, 0.941176, 1.0)
386
+ static readonly hotPink = new Color(1.0, 0.411765, 0.705882, 1.0)
387
+ static readonly indianRed = new Color(0.803922, 0.360784, 0.360784, 1.0)
388
+ static readonly indigo = new Color(0.294118, 0.0, 0.509804, 1.0)
389
+ static readonly ivory = new Color(1.0, 1.0, 0.941176, 1.0)
390
+ static readonly khaki = new Color(0.941176, 0.901961, 0.54902, 1.0)
391
+ static readonly lavender = new Color(0.901961, 0.901961, 0.980392, 1.0)
392
+ static readonly lavenderBlush = new Color(1.0, 0.941176, 0.960784, 1.0)
393
+ static readonly lawnGreen = new Color(0.486275, 0.988235, 0.0, 1.0)
394
+ static readonly lemonChiffon = new Color(1.0, 0.980392, 0.803922, 1.0)
395
+ static readonly lightBlue = new Color(0.678431, 0.847059, 0.901961, 1.0)
396
+ static readonly lightCoral = new Color(0.941176, 0.501961, 0.501961, 1.0)
397
+ static readonly lightCyan = new Color(0.878431, 1.0, 1.0, 1.0)
398
+ static readonly lightGoldenrodYellow = new Color(0.980392, 0.980392, 0.823529, 1.0)
399
+ static readonly lightGreen = new Color(0.564706, 0.933333, 0.564706, 1.0)
400
+ static readonly lightGrey = new Color(0.827451, 0.827451, 0.827451, 1.0)
401
+ static readonly lightPink = new Color(1.0, 0.713725, 0.756863, 1.0)
402
+ static readonly lightSalmon = new Color(1.0, 0.627451, 0.478431, 1.0)
403
+ static readonly lightSeaGreen = new Color(0.12549, 0.698039, 0.666667, 1.0)
404
+ static readonly lightSkyBlue = new Color(0.529412, 0.807843, 0.980392, 1.0)
405
+ static readonly lightSlateGray = new Color(0.466667, 0.533333, 0.6, 1.0)
406
+ static readonly lightSteelBlue = new Color(0.690196, 0.768627, 0.870588, 1.0)
407
+ static readonly lightYellow = new Color(1.0, 1.0, 0.878431, 1.0)
408
+ static readonly lime = new Color(0.0, 1.0, 0.0, 1.0)
409
+ static readonly limeGreen = new Color(0.196078, 0.803922, 0.196078, 1.0)
410
+ static readonly linen = new Color(0.980392, 0.941176, 0.901961, 1.0)
411
+ static readonly magenta = new Color(1.0, 0.0, 1.0, 1.0)
412
+ static readonly maroon = new Color(0.501961, 0.0, 0.0, 1.0)
413
+ static readonly mediumAquamarine = new Color(0.4, 0.803922, 0.666667, 1.0)
414
+ static readonly mediumBlue = new Color(0.0, 0.0, 0.803922, 1.0)
415
+ static readonly mediumOrchid = new Color(0.729412, 0.333333, 0.827451, 1.0)
416
+ static readonly mediumPurple = new Color(0.576471, 0.439216, 0.858824, 1.0)
417
+ static readonly mediumSeaGreen = new Color(0.235294, 0.701961, 0.443137, 1.0)
418
+ static readonly mediumSlateBlue = new Color(0.482353, 0.407843, 0.933333, 1.0)
419
+ static readonly mediumSpringGreen = new Color(0.0, 0.980392, 0.603922, 1.0)
420
+ static readonly mediumTurquoise = new Color(0.282353, 0.819608, 0.8, 1.0)
421
+ static readonly mediumVioletRed = new Color(0.780392, 0.082353, 0.521569, 1.0)
422
+ static readonly midnightBlue = new Color(0.098039, 0.098039, 0.439216, 1.0)
423
+ static readonly mintCream = new Color(0.960784, 1.0, 0.980392, 1.0)
424
+ static readonly mistyRose = new Color(1.0, 0.894118, 0.882353, 1.0)
425
+ static readonly moccasin = new Color(1.0, 0.894118, 0.709804, 1.0)
426
+ static readonly navajoWhite = new Color(1.0, 0.870588, 0.678431, 1.0)
427
+ static readonly navy = new Color(0.0, 0.0, 0.501961, 1.0)
428
+ static readonly oldLace = new Color(0.992157, 0.960784, 0.901961, 1.0)
429
+ static readonly olive = new Color(0.501961, 0.501961, 0.0, 1.0)
430
+ static readonly oliveDrab = new Color(0.419608, 0.556863, 0.137255, 1.0)
431
+ static readonly orange = new Color(1.0, 0.647059, 0.0, 1.0)
432
+ static readonly orangeRed = new Color(1.0, 0.270588, 0.0, 1.0)
433
+ static readonly orchid = new Color(0.854902, 0.439216, 0.839216, 1.0)
434
+ static readonly paleGoldenrod = new Color(0.933333, 0.909804, 0.666667, 1.0)
435
+ static readonly paleGreen = new Color(0.596078, 0.984314, 0.596078, 1.0)
436
+ static readonly paleTurquoise = new Color(0.686275, 0.933333, 0.933333, 1.0)
437
+ static readonly paleVioletRed = new Color(0.858824, 0.439216, 0.576471, 1.0)
438
+ static readonly papayaWhip = new Color(1.0, 0.937255, 0.835294, 1.0)
439
+ static readonly peachPuff = new Color(1.0, 0.854902, 0.72549, 1.0)
440
+ static readonly peru = new Color(0.803922, 0.521569, 0.247059, 1.0)
441
+ static readonly pink = new Color(1.0, 0.752941, 0.796078, 1.0)
442
+ static readonly plum = new Color(0.866667, 0.627451, 0.866667, 1.0)
443
+ static readonly powderBlue = new Color(0.690196, 0.878431, 0.901961, 1.0)
444
+ static readonly purple = new Color(0.501961, 0.0, 0.501961, 1.0)
445
+ static readonly red = new Color(1.0, 0.0, 0.0, 1.0)
446
+ static readonly rosyBrown = new Color(0.737255, 0.560784, 0.560784, 1.0)
447
+ static readonly royalBlue = new Color(0.254902, 0.411765, 0.882353, 1.0)
448
+ static readonly saddleBrown = new Color(0.545098, 0.270588, 0.07451, 1.0)
449
+ static readonly salmon = new Color(0.980392, 0.501961, 0.447059, 1.0)
450
+ static readonly sandyBrown = new Color(0.956863, 0.643137, 0.376471, 1.0)
451
+ static readonly seaGreen = new Color(0.180392, 0.545098, 0.380392, 1.0)
452
+ static readonly seashell = new Color(1.0, 0.960784, 0.933333, 1.0)
453
+ static readonly sienna = new Color(0.627451, 0.321569, 0.176471, 1.0)
454
+ static readonly silver = new Color(0.752941, 0.752941, 0.752941, 1.0)
455
+ static readonly skyBlue = new Color(0.529412, 0.807843, 0.921569, 1.0)
456
+ static readonly slateBlue = new Color(0.415686, 0.352941, 0.803922, 1.0)
457
+ static readonly slateGray = new Color(0.466667, 0.533333, 0.6, 1.0)
458
+ static readonly snow = new Color(1.0, 0.980392, 0.980392, 1.0)
459
+ static readonly springGreen = new Color(0.0, 1.0, 0.498039, 1.0)
460
+ static readonly steelBlue = new Color(0.27451, 0.509804, 0.705882, 1.0)
461
+ static readonly tan = new Color(0.823529, 0.705882, 0.54902, 1.0)
462
+ static readonly teal = new Color(0.0, 0.501961, 0.501961, 1.0)
463
+ static readonly thistle = new Color(0.847059, 0.74902, 0.847059, 1.0)
464
+ static readonly tomato = new Color(1.0, 0.388235, 0.278431, 1.0)
465
+ static readonly transparent = new Color(0.0, 0.0, 0.0, 0.0)
466
+ static readonly turquoise = new Color(0.25098, 0.878431, 0.815686, 1.0)
467
+ static readonly violet = new Color(0.933333, 0.509804, 0.933333, 1.0)
468
+ static readonly wheat = new Color(0.960784, 0.870588, 0.701961, 1.0)
469
+ static readonly white = new Color(1.0, 1.0, 1.0, 1.0)
470
+ static readonly whiteSmoke = new Color(0.960784, 0.960784, 0.960784, 1.0)
471
+ static readonly yellow = new Color(1.0, 1.0, 0.0, 1.0)
472
+ static readonly yellowGreen = new Color(0.603922, 0.803922, 0.196078, 1.0)
473
+
474
+ static readonly names: string[] = ['aliceBlue', 'antiqueWhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedAlmond', 'blue', 'blueViolet', 'brown', 'burlyWood', 'cadetBlue', 'chartreuse', 'chocolate', 'coral', 'cornflowerBlue', 'cornsilk', 'crimson', 'cyan', 'darkBlue', 'darkCyan', 'darkGoldenrod', 'darkGray', 'darkGreen', 'darkKhaki', 'darkMagenta', 'darkOliveGreen', 'darkOrange', 'darkOrchid', 'darkRed', 'darkSalmon', 'darkSeaGreen', 'darkSlateBlue', 'darkSlateGray', 'darkTurquoise', 'darkViolet', 'deepPink', 'deepSkyBlue', 'dimGray', 'dodgerBlue', 'fireBrick', 'floralWhite', 'forestGreen', 'fuchsia', 'gainsboro', 'ghostWhite', 'gold', 'goldenrod', 'gray', 'green', 'greenYellow', 'honeydew', 'hotPink', 'indianRed', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderBlush', 'lawnGreen', 'lemonChiffon', 'lightBlue', 'lightCoral', 'lightCyan', 'lightGoldenrodYellow', 'lightGreen', 'lightGrey', 'lightPink', 'lightSalmon', 'lightSeaGreen', 'lightSkyBlue', 'lightSlateGray', 'lightSteelBlue', 'lightYellow', 'lime', 'limeGreen', 'linen', 'magenta', 'maroon', 'mediumAquamarine', 'mediumBlue', 'mediumOrchid', 'mediumPurple', 'mediumSeaGreen', 'mediumSlateBlue', 'mediumSpringGreen', 'mediumTurquoise', 'mediumVioletRed', 'midnightBlue', 'mintCream', 'mistyRose', 'moccasin', 'navajoWhite', 'navy', 'oldLace', 'olive', 'oliveDrab', 'orange', 'orangeRed', 'orchid', 'paleGoldenrod', 'paleGreen', 'paleTurquoise', 'paleVioletRed', 'papayaWhip', 'peachPuff', 'peru', 'pink', 'plum', 'powderBlue', 'purple', 'red', 'rosyBrown', 'royalBlue', 'saddleBrown', 'salmon', 'sandyBrown', 'seaGreen', 'seashell', 'sienna', 'silver', 'skyBlue', 'slateBlue', 'slateGray', 'snow', 'springGreen', 'steelBlue', 'tan', 'teal', 'thistle', 'tomato', 'transparent', 'turquoise', 'violet', 'wheat', 'white', 'whiteSmoke', 'yellow', 'yellowGreen']
475
+
476
+ static get colors() {
477
+ if(_colors === undefined) {
478
+ _colors = {}
479
+ const _c=_colors as any
480
+ const o=Color as any
481
+
482
+ Color.names.forEach(name => {
483
+ _c[name] = o[name]
484
+ })
485
+ }
486
+
487
+ return _colors
488
+ }
489
+
490
+ // #endregion
491
+ }
492
+
493
+ export class MutableColor extends Color {
494
+ constructor(r: number, g: number, b: number, a: number = 1.0) {
495
+ super(r, g, b, a)
496
+ }
497
+
498
+ override get r() {
499
+ return this._r
500
+ }
501
+
502
+ override set r(r: number) {
503
+ this._r = r
504
+ this._invalidateCaches()
505
+ }
506
+
507
+ override get g() {
508
+ return this._g
509
+ }
510
+
511
+ override set g(g: number) {
512
+ this._g = g
513
+ this._invalidateCaches()
514
+ }
515
+
516
+ override get b() {
517
+ return this._b
518
+ }
519
+
520
+ override set b(b: number) {
521
+ this._b = b
522
+ this._invalidateCaches()
523
+ }
524
+
525
+ override get a() {
526
+ return this._a
527
+ }
528
+
529
+ override set a(a: number) {
530
+ this._a = a
531
+ this._invalidateCaches()
532
+ }
533
+
534
+ /**
535
+ * Add two colors together and modify the current color
536
+ * @param {Color} c Color to add
537
+ * @returns {Color}
538
+ */
539
+ addIn(c: Color): Color {
540
+ this._r += c.r
541
+ this._g += c.g
542
+ this._b += c.b
543
+ this._a += c.a
544
+ this._invalidateCaches()
545
+ return this
546
+ }
547
+
548
+ /**
549
+ * Subtract two colors and modify the current color
550
+ * @param {Color} c Color to subtract
551
+ * @returns {Color}
552
+ */
553
+ subIn(c: Color): Color {
554
+ this._r -= c.r
555
+ this._g -= c.g
556
+ this._b -= c.b
557
+ this._a -= c.a
558
+ this._invalidateCaches()
559
+ return this
560
+ }
561
+
562
+ /**
563
+ * Multiply a color by a scalar and modify the current color
564
+ * @param {number} n Scalar to multiply
565
+ * @returns {Color}
566
+ */
567
+ mulIn(n: number): Color {
568
+ this._r *= n
569
+ this._g *= n
570
+ this._b *= n
571
+ this._a *= n
572
+ this._invalidateCaches()
573
+ return this
574
+ }
575
+
576
+ /**
577
+ * Divide a color by a scalar and modify the current color
578
+ * @param {number} n Scalar to divide
579
+ * @returns {Color}
580
+ */
581
+ divIn(n: number): Color {
582
+ this._r /= n
583
+ this._g /= n
584
+ this._b /= n
585
+ this._a /= n
586
+ this._invalidateCaches()
587
+ return this
588
+ }
589
+ }