1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | import type { StyleProps } from './commonTypes';
|
11 | import { makeShareable } from './core';
|
12 | import { isAndroid, isWeb } from './PlatformChecker';
|
13 |
|
14 | interface RGB {
|
15 | r: number;
|
16 | g: number;
|
17 | b: number;
|
18 | }
|
19 |
|
20 | interface HSV {
|
21 | h: number;
|
22 | s: number;
|
23 | v: number;
|
24 | }
|
25 |
|
26 | const NUMBER: string = '[-+]?\\d*\\.?\\d+';
|
27 | const PERCENTAGE = NUMBER + '%';
|
28 |
|
29 | function call(...args: (RegExp | string)[]) {
|
30 | return '\\(\\s*(' + args.join(')\\s*,?\\s*(') + ')\\s*\\)';
|
31 | }
|
32 |
|
33 | function callWithSlashSeparator(...args: (RegExp | string)[]) {
|
34 | return (
|
35 | '\\(\\s*(' +
|
36 | args.slice(0, args.length - 1).join(')\\s*,?\\s*(') +
|
37 | ')\\s*/\\s*(' +
|
38 | args[args.length - 1] +
|
39 | ')\\s*\\)'
|
40 | );
|
41 | }
|
42 |
|
43 | function commaSeparatedCall(...args: (RegExp | string)[]) {
|
44 | return '\\(\\s*(' + args.join(')\\s*,\\s*(') + ')\\s*\\)';
|
45 | }
|
46 |
|
47 | const MATCHERS = {
|
48 | rgb: new RegExp('rgb' + call(NUMBER, NUMBER, NUMBER)),
|
49 | rgba: new RegExp(
|
50 | 'rgba(' +
|
51 | commaSeparatedCall(NUMBER, NUMBER, NUMBER, NUMBER) +
|
52 | '|' +
|
53 | callWithSlashSeparator(NUMBER, NUMBER, NUMBER, NUMBER) +
|
54 | ')'
|
55 | ),
|
56 | hsl: new RegExp('hsl' + call(NUMBER, PERCENTAGE, PERCENTAGE)),
|
57 | hsla: new RegExp(
|
58 | 'hsla(' +
|
59 | commaSeparatedCall(NUMBER, PERCENTAGE, PERCENTAGE, NUMBER) +
|
60 | '|' +
|
61 | callWithSlashSeparator(NUMBER, PERCENTAGE, PERCENTAGE, NUMBER) +
|
62 | ')'
|
63 | ),
|
64 | hwb: new RegExp('hwb' + call(NUMBER, PERCENTAGE, PERCENTAGE)),
|
65 | hex3: /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
66 | hex4: /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
67 | hex6: /^#([0-9a-fA-F]{6})$/,
|
68 | hex8: /^#([0-9a-fA-F]{8})$/,
|
69 | };
|
70 |
|
71 | function hue2rgb(p: number, q: number, t: number): number {
|
72 | 'worklet';
|
73 | if (t < 0) {
|
74 | t += 1;
|
75 | }
|
76 | if (t > 1) {
|
77 | t -= 1;
|
78 | }
|
79 | if (t < 1 / 6) {
|
80 | return p + (q - p) * 6 * t;
|
81 | }
|
82 | if (t < 1 / 2) {
|
83 | return q;
|
84 | }
|
85 | if (t < 2 / 3) {
|
86 | return p + (q - p) * (2 / 3 - t) * 6;
|
87 | }
|
88 | return p;
|
89 | }
|
90 |
|
91 | function hslToRgb(h: number, s: number, l: number): number {
|
92 | 'worklet';
|
93 | const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
94 | const p = 2 * l - q;
|
95 | const r = hue2rgb(p, q, h + 1 / 3);
|
96 | const g = hue2rgb(p, q, h);
|
97 | const b = hue2rgb(p, q, h - 1 / 3);
|
98 |
|
99 | return (
|
100 | (Math.round(r * 255) << 24) |
|
101 | (Math.round(g * 255) << 16) |
|
102 | (Math.round(b * 255) << 8)
|
103 | );
|
104 | }
|
105 |
|
106 | function hwbToRgb(h: number, w: number, b: number): number {
|
107 | 'worklet';
|
108 | if (w + b >= 1) {
|
109 | const gray = Math.round((w * 255) / (w + b));
|
110 |
|
111 | return (gray << 24) | (gray << 16) | (gray << 8);
|
112 | }
|
113 |
|
114 | const red = hue2rgb(0, 1, h + 1 / 3) * (1 - w - b) + w;
|
115 | const green = hue2rgb(0, 1, h) * (1 - w - b) + w;
|
116 | const blue = hue2rgb(0, 1, h - 1 / 3) * (1 - w - b) + w;
|
117 |
|
118 | return (
|
119 | (Math.round(red * 255) << 24) |
|
120 | (Math.round(green * 255) << 16) |
|
121 | (Math.round(blue * 255) << 8)
|
122 | );
|
123 | }
|
124 |
|
125 | function parse255(str: string): number {
|
126 | 'worklet';
|
127 | const int = Number.parseInt(str, 10);
|
128 | if (int < 0) {
|
129 | return 0;
|
130 | }
|
131 | if (int > 255) {
|
132 | return 255;
|
133 | }
|
134 | return int;
|
135 | }
|
136 |
|
137 | function parse360(str: string): number {
|
138 | 'worklet';
|
139 | const int = Number.parseFloat(str);
|
140 | return (((int % 360) + 360) % 360) / 360;
|
141 | }
|
142 |
|
143 | function parse1(str: string): number {
|
144 | 'worklet';
|
145 | const num = Number.parseFloat(str);
|
146 | if (num < 0) {
|
147 | return 0;
|
148 | }
|
149 | if (num > 1) {
|
150 | return 255;
|
151 | }
|
152 | return Math.round(num * 255);
|
153 | }
|
154 |
|
155 | function parsePercentage(str: string): number {
|
156 | 'worklet';
|
157 |
|
158 | const int = Number.parseFloat(str);
|
159 | if (int < 0) {
|
160 | return 0;
|
161 | }
|
162 | if (int > 100) {
|
163 | return 1;
|
164 | }
|
165 | return int / 100;
|
166 | }
|
167 |
|
168 | const names: Record<string, number> = makeShareable({
|
169 | transparent: 0x00000000,
|
170 |
|
171 |
|
172 | aliceblue: 0xf0f8ffff,
|
173 | antiquewhite: 0xfaebd7ff,
|
174 | aqua: 0x00ffffff,
|
175 | aquamarine: 0x7fffd4ff,
|
176 | azure: 0xf0ffffff,
|
177 | beige: 0xf5f5dcff,
|
178 | bisque: 0xffe4c4ff,
|
179 | black: 0x000000ff,
|
180 | blanchedalmond: 0xffebcdff,
|
181 | blue: 0x0000ffff,
|
182 | blueviolet: 0x8a2be2ff,
|
183 | brown: 0xa52a2aff,
|
184 | burlywood: 0xdeb887ff,
|
185 | burntsienna: 0xea7e5dff,
|
186 | cadetblue: 0x5f9ea0ff,
|
187 | chartreuse: 0x7fff00ff,
|
188 | chocolate: 0xd2691eff,
|
189 | coral: 0xff7f50ff,
|
190 | cornflowerblue: 0x6495edff,
|
191 | cornsilk: 0xfff8dcff,
|
192 | crimson: 0xdc143cff,
|
193 | cyan: 0x00ffffff,
|
194 | darkblue: 0x00008bff,
|
195 | darkcyan: 0x008b8bff,
|
196 | darkgoldenrod: 0xb8860bff,
|
197 | darkgray: 0xa9a9a9ff,
|
198 | darkgreen: 0x006400ff,
|
199 | darkgrey: 0xa9a9a9ff,
|
200 | darkkhaki: 0xbdb76bff,
|
201 | darkmagenta: 0x8b008bff,
|
202 | darkolivegreen: 0x556b2fff,
|
203 | darkorange: 0xff8c00ff,
|
204 | darkorchid: 0x9932ccff,
|
205 | darkred: 0x8b0000ff,
|
206 | darksalmon: 0xe9967aff,
|
207 | darkseagreen: 0x8fbc8fff,
|
208 | darkslateblue: 0x483d8bff,
|
209 | darkslategray: 0x2f4f4fff,
|
210 | darkslategrey: 0x2f4f4fff,
|
211 | darkturquoise: 0x00ced1ff,
|
212 | darkviolet: 0x9400d3ff,
|
213 | deeppink: 0xff1493ff,
|
214 | deepskyblue: 0x00bfffff,
|
215 | dimgray: 0x696969ff,
|
216 | dimgrey: 0x696969ff,
|
217 | dodgerblue: 0x1e90ffff,
|
218 | firebrick: 0xb22222ff,
|
219 | floralwhite: 0xfffaf0ff,
|
220 | forestgreen: 0x228b22ff,
|
221 | fuchsia: 0xff00ffff,
|
222 | gainsboro: 0xdcdcdcff,
|
223 | ghostwhite: 0xf8f8ffff,
|
224 | gold: 0xffd700ff,
|
225 | goldenrod: 0xdaa520ff,
|
226 | gray: 0x808080ff,
|
227 | green: 0x008000ff,
|
228 | greenyellow: 0xadff2fff,
|
229 | grey: 0x808080ff,
|
230 | honeydew: 0xf0fff0ff,
|
231 | hotpink: 0xff69b4ff,
|
232 | indianred: 0xcd5c5cff,
|
233 | indigo: 0x4b0082ff,
|
234 | ivory: 0xfffff0ff,
|
235 | khaki: 0xf0e68cff,
|
236 | lavender: 0xe6e6faff,
|
237 | lavenderblush: 0xfff0f5ff,
|
238 | lawngreen: 0x7cfc00ff,
|
239 | lemonchiffon: 0xfffacdff,
|
240 | lightblue: 0xadd8e6ff,
|
241 | lightcoral: 0xf08080ff,
|
242 | lightcyan: 0xe0ffffff,
|
243 | lightgoldenrodyellow: 0xfafad2ff,
|
244 | lightgray: 0xd3d3d3ff,
|
245 | lightgreen: 0x90ee90ff,
|
246 | lightgrey: 0xd3d3d3ff,
|
247 | lightpink: 0xffb6c1ff,
|
248 | lightsalmon: 0xffa07aff,
|
249 | lightseagreen: 0x20b2aaff,
|
250 | lightskyblue: 0x87cefaff,
|
251 | lightslategray: 0x778899ff,
|
252 | lightslategrey: 0x778899ff,
|
253 | lightsteelblue: 0xb0c4deff,
|
254 | lightyellow: 0xffffe0ff,
|
255 | lime: 0x00ff00ff,
|
256 | limegreen: 0x32cd32ff,
|
257 | linen: 0xfaf0e6ff,
|
258 | magenta: 0xff00ffff,
|
259 | maroon: 0x800000ff,
|
260 | mediumaquamarine: 0x66cdaaff,
|
261 | mediumblue: 0x0000cdff,
|
262 | mediumorchid: 0xba55d3ff,
|
263 | mediumpurple: 0x9370dbff,
|
264 | mediumseagreen: 0x3cb371ff,
|
265 | mediumslateblue: 0x7b68eeff,
|
266 | mediumspringgreen: 0x00fa9aff,
|
267 | mediumturquoise: 0x48d1ccff,
|
268 | mediumvioletred: 0xc71585ff,
|
269 | midnightblue: 0x191970ff,
|
270 | mintcream: 0xf5fffaff,
|
271 | mistyrose: 0xffe4e1ff,
|
272 | moccasin: 0xffe4b5ff,
|
273 | navajowhite: 0xffdeadff,
|
274 | navy: 0x000080ff,
|
275 | oldlace: 0xfdf5e6ff,
|
276 | olive: 0x808000ff,
|
277 | olivedrab: 0x6b8e23ff,
|
278 | orange: 0xffa500ff,
|
279 | orangered: 0xff4500ff,
|
280 | orchid: 0xda70d6ff,
|
281 | palegoldenrod: 0xeee8aaff,
|
282 | palegreen: 0x98fb98ff,
|
283 | paleturquoise: 0xafeeeeff,
|
284 | palevioletred: 0xdb7093ff,
|
285 | papayawhip: 0xffefd5ff,
|
286 | peachpuff: 0xffdab9ff,
|
287 | peru: 0xcd853fff,
|
288 | pink: 0xffc0cbff,
|
289 | plum: 0xdda0ddff,
|
290 | powderblue: 0xb0e0e6ff,
|
291 | purple: 0x800080ff,
|
292 | rebeccapurple: 0x663399ff,
|
293 | red: 0xff0000ff,
|
294 | rosybrown: 0xbc8f8fff,
|
295 | royalblue: 0x4169e1ff,
|
296 | saddlebrown: 0x8b4513ff,
|
297 | salmon: 0xfa8072ff,
|
298 | sandybrown: 0xf4a460ff,
|
299 | seagreen: 0x2e8b57ff,
|
300 | seashell: 0xfff5eeff,
|
301 | sienna: 0xa0522dff,
|
302 | silver: 0xc0c0c0ff,
|
303 | skyblue: 0x87ceebff,
|
304 | slateblue: 0x6a5acdff,
|
305 | slategray: 0x708090ff,
|
306 | slategrey: 0x708090ff,
|
307 | snow: 0xfffafaff,
|
308 | springgreen: 0x00ff7fff,
|
309 | steelblue: 0x4682b4ff,
|
310 | tan: 0xd2b48cff,
|
311 | teal: 0x008080ff,
|
312 | thistle: 0xd8bfd8ff,
|
313 | tomato: 0xff6347ff,
|
314 | turquoise: 0x40e0d0ff,
|
315 | violet: 0xee82eeff,
|
316 | wheat: 0xf5deb3ff,
|
317 | white: 0xffffffff,
|
318 | whitesmoke: 0xf5f5f5ff,
|
319 | yellow: 0xffff00ff,
|
320 | yellowgreen: 0x9acd32ff,
|
321 | });
|
322 |
|
323 |
|
324 | export const ColorProperties = makeShareable([
|
325 | 'backgroundColor',
|
326 | 'borderBottomColor',
|
327 | 'borderColor',
|
328 | 'borderLeftColor',
|
329 | 'borderRightColor',
|
330 | 'borderTopColor',
|
331 | 'borderStartColor',
|
332 | 'borderEndColor',
|
333 | 'borderBlockColor',
|
334 | 'borderBlockEndColor',
|
335 | 'borderBlockStartColor',
|
336 | 'color',
|
337 | 'shadowColor',
|
338 | 'textDecorationColor',
|
339 | 'tintColor',
|
340 | 'textShadowColor',
|
341 | 'overlayColor',
|
342 | ]);
|
343 |
|
344 | export function normalizeColor(color: unknown): number | null {
|
345 | 'worklet';
|
346 |
|
347 | if (typeof color === 'number') {
|
348 | if (color >>> 0 === color && color >= 0 && color <= 0xffffffff) {
|
349 | return color;
|
350 | }
|
351 | return null;
|
352 | }
|
353 |
|
354 | if (typeof color !== 'string') {
|
355 | return null;
|
356 | }
|
357 |
|
358 | let match: RegExpExecArray | null | undefined;
|
359 |
|
360 |
|
361 | if ((match = MATCHERS.hex6.exec(color))) {
|
362 | return Number.parseInt(match[1] + 'ff', 16) >>> 0;
|
363 | }
|
364 |
|
365 | if (names[color] !== undefined) {
|
366 | return names[color];
|
367 | }
|
368 |
|
369 | if ((match = MATCHERS.rgb.exec(color))) {
|
370 | return (
|
371 |
|
372 | ((parse255(match[1]) << 24) |
|
373 | (parse255(match[2]) << 16) |
|
374 | (parse255(match[3]) << 8) |
|
375 | 0x000000ff) >>>
|
376 | 0
|
377 | );
|
378 | }
|
379 |
|
380 | if ((match = MATCHERS.rgba.exec(color))) {
|
381 |
|
382 | if (match[6] !== undefined) {
|
383 | return (
|
384 | ((parse255(match[6]) << 24) |
|
385 | (parse255(match[7]) << 16) |
|
386 | (parse255(match[8]) << 8) |
|
387 | parse1(match[9])) >>>
|
388 | 0
|
389 | );
|
390 | }
|
391 |
|
392 |
|
393 | return (
|
394 | ((parse255(match[2]) << 24) |
|
395 | (parse255(match[3]) << 16) |
|
396 | (parse255(match[4]) << 8) |
|
397 | parse1(match[5])) >>>
|
398 | 0
|
399 | );
|
400 | }
|
401 |
|
402 | if ((match = MATCHERS.hex3.exec(color))) {
|
403 | return (
|
404 | Number.parseInt(
|
405 | match[1] +
|
406 | match[1] +
|
407 | match[2] +
|
408 | match[2] +
|
409 | match[3] +
|
410 | match[3] +
|
411 | 'ff',
|
412 | 16
|
413 | ) >>> 0
|
414 | );
|
415 | }
|
416 |
|
417 |
|
418 | if ((match = MATCHERS.hex8.exec(color))) {
|
419 | return Number.parseInt(match[1], 16) >>> 0;
|
420 | }
|
421 |
|
422 | if ((match = MATCHERS.hex4.exec(color))) {
|
423 | return (
|
424 | Number.parseInt(
|
425 | match[1] +
|
426 | match[1] +
|
427 | match[2] +
|
428 | match[2] +
|
429 | match[3] +
|
430 | match[3] +
|
431 | match[4] +
|
432 | match[4],
|
433 | 16
|
434 | ) >>> 0
|
435 | );
|
436 | }
|
437 |
|
438 | if ((match = MATCHERS.hsl.exec(color))) {
|
439 | return (
|
440 | (hslToRgb(
|
441 | parse360(match[1]),
|
442 | parsePercentage(match[2]),
|
443 | parsePercentage(match[3])
|
444 | ) |
|
445 | 0x000000ff) >>>
|
446 | 0
|
447 | );
|
448 | }
|
449 |
|
450 | if ((match = MATCHERS.hsla.exec(color))) {
|
451 |
|
452 | if (match[6] !== undefined) {
|
453 | return (
|
454 | (hslToRgb(
|
455 | parse360(match[6]),
|
456 | parsePercentage(match[7]),
|
457 | parsePercentage(match[8])
|
458 | ) |
|
459 | parse1(match[9])) >>>
|
460 | 0
|
461 | );
|
462 | }
|
463 |
|
464 |
|
465 | return (
|
466 | (hslToRgb(
|
467 | parse360(match[2]),
|
468 | parsePercentage(match[3]),
|
469 | parsePercentage(match[4])
|
470 | ) |
|
471 | parse1(match[5])) >>>
|
472 | 0
|
473 | );
|
474 | }
|
475 |
|
476 | if ((match = MATCHERS.hwb.exec(color))) {
|
477 | return (
|
478 | (hwbToRgb(
|
479 | parse360(match[1]),
|
480 | parsePercentage(match[2]),
|
481 | parsePercentage(match[3])
|
482 | ) |
|
483 | 0x000000ff) >>>
|
484 | 0
|
485 | );
|
486 | }
|
487 |
|
488 | return null;
|
489 | }
|
490 |
|
491 | export const opacity = (c: number): number => {
|
492 | 'worklet';
|
493 | return ((c >> 24) & 255) / 255;
|
494 | };
|
495 |
|
496 | export const red = (c: number): number => {
|
497 | 'worklet';
|
498 | return (c >> 16) & 255;
|
499 | };
|
500 |
|
501 | export const green = (c: number): number => {
|
502 | 'worklet';
|
503 | return (c >> 8) & 255;
|
504 | };
|
505 |
|
506 | export const blue = (c: number): number => {
|
507 | 'worklet';
|
508 | return c & 255;
|
509 | };
|
510 |
|
511 | const IS_WEB = isWeb();
|
512 | const IS_ANDROID = isAndroid();
|
513 |
|
514 | export const rgbaColor = (
|
515 | r: number,
|
516 | g: number,
|
517 | b: number,
|
518 | alpha = 1
|
519 | ): number | string => {
|
520 | 'worklet';
|
521 | if (IS_WEB || !_WORKLET) {
|
522 | return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
523 | }
|
524 |
|
525 | const c =
|
526 | Math.round(alpha * 255) * (1 << 24) +
|
527 | Math.round(r) * (1 << 16) +
|
528 | Math.round(g) * (1 << 8) +
|
529 | Math.round(b);
|
530 | if (IS_ANDROID) {
|
531 |
|
532 | return c < (1 << 31) >>> 0 ? c : c - 4294967296;
|
533 | }
|
534 | return c;
|
535 | };
|
536 |
|
537 |
|
538 |
|
539 |
|
540 |
|
541 |
|
542 |
|
543 |
|
544 | export function RGBtoHSV(r: number, g: number, b: number): HSV {
|
545 | 'worklet';
|
546 | const max = Math.max(r, g, b);
|
547 | const min = Math.min(r, g, b);
|
548 | const d = max - min;
|
549 | const s = max === 0 ? 0 : d / max;
|
550 | const v = max / 255;
|
551 |
|
552 | let h = 0;
|
553 |
|
554 | switch (max) {
|
555 | case min:
|
556 | break;
|
557 | case r:
|
558 | h = g - b + d * (g < b ? 6 : 0);
|
559 | h /= 6 * d;
|
560 | break;
|
561 | case g:
|
562 | h = b - r + d * 2;
|
563 | h /= 6 * d;
|
564 | break;
|
565 | case b:
|
566 | h = r - g + d * 4;
|
567 | h /= 6 * d;
|
568 | break;
|
569 | }
|
570 |
|
571 | return { h, s, v };
|
572 | }
|
573 |
|
574 |
|
575 |
|
576 |
|
577 |
|
578 |
|
579 |
|
580 |
|
581 | function HSVtoRGB(h: number, s: number, v: number): RGB {
|
582 | 'worklet';
|
583 | let r, g, b;
|
584 |
|
585 | const i = Math.floor(h * 6);
|
586 | const f = h * 6 - i;
|
587 | const p = v * (1 - s);
|
588 | const q = v * (1 - f * s);
|
589 | const t = v * (1 - (1 - f) * s);
|
590 | switch ((i % 6) as 0 | 1 | 2 | 3 | 4 | 5) {
|
591 | case 0:
|
592 | [r, g, b] = [v, t, p];
|
593 | break;
|
594 | case 1:
|
595 | [r, g, b] = [q, v, p];
|
596 | break;
|
597 | case 2:
|
598 | [r, g, b] = [p, v, t];
|
599 | break;
|
600 | case 3:
|
601 | [r, g, b] = [p, q, v];
|
602 | break;
|
603 | case 4:
|
604 | [r, g, b] = [t, p, v];
|
605 | break;
|
606 | case 5:
|
607 | [r, g, b] = [v, p, q];
|
608 | break;
|
609 | }
|
610 | return {
|
611 | r: Math.round(r * 255),
|
612 | g: Math.round(g * 255),
|
613 | b: Math.round(b * 255),
|
614 | };
|
615 | }
|
616 |
|
617 | export const hsvToColor = (
|
618 | h: number,
|
619 | s: number,
|
620 | v: number,
|
621 | a: number
|
622 | ): number | string => {
|
623 | 'worklet';
|
624 | const { r, g, b } = HSVtoRGB(h, s, v);
|
625 | return rgbaColor(r, g, b, a);
|
626 | };
|
627 |
|
628 | function processColorInitially(color: unknown): number | null | undefined {
|
629 | 'worklet';
|
630 | if (color === null || color === undefined || typeof color === 'number') {
|
631 | return color;
|
632 | }
|
633 |
|
634 | let normalizedColor = normalizeColor(color);
|
635 |
|
636 | if (normalizedColor === null || normalizedColor === undefined) {
|
637 | return undefined;
|
638 | }
|
639 |
|
640 | if (typeof normalizedColor !== 'number') {
|
641 | return null;
|
642 | }
|
643 |
|
644 | normalizedColor = ((normalizedColor << 24) | (normalizedColor >>> 8)) >>> 0;
|
645 | return normalizedColor;
|
646 | }
|
647 |
|
648 | export function isColor(value: unknown): boolean {
|
649 | 'worklet';
|
650 | if (typeof value !== 'string') {
|
651 | return false;
|
652 | }
|
653 | return processColorInitially(value) != null;
|
654 | }
|
655 |
|
656 | export function processColor(color: unknown): number | null | undefined {
|
657 | 'worklet';
|
658 | let normalizedColor = processColorInitially(color);
|
659 | if (normalizedColor === null || normalizedColor === undefined) {
|
660 | return undefined;
|
661 | }
|
662 |
|
663 | if (typeof normalizedColor !== 'number') {
|
664 | return null;
|
665 | }
|
666 |
|
667 | if (IS_ANDROID) {
|
668 |
|
669 |
|
670 |
|
671 |
|
672 | normalizedColor = normalizedColor | 0x0;
|
673 | }
|
674 |
|
675 | return normalizedColor;
|
676 | }
|
677 |
|
678 | export function processColorsInProps(props: StyleProps) {
|
679 | 'worklet';
|
680 | for (const key in props) {
|
681 | if (ColorProperties.includes(key)) {
|
682 | props[key] = processColor(props[key]);
|
683 | }
|
684 | }
|
685 | }
|
686 |
|
687 | export type ParsedColorArray = [number, number, number, number];
|
688 |
|
689 | export function convertToRGBA(color: unknown): ParsedColorArray {
|
690 | 'worklet';
|
691 | const processedColor = processColorInitially(color)!;
|
692 | const a = (processedColor >>> 24) / 255;
|
693 | const r = ((processedColor << 8) >>> 24) / 255;
|
694 | const g = ((processedColor << 16) >>> 24) / 255;
|
695 | const b = ((processedColor << 24) >>> 24) / 255;
|
696 | return [r, g, b, a];
|
697 | }
|
698 |
|
699 | export function rgbaArrayToRGBAColor(RGBA: ParsedColorArray): string {
|
700 | 'worklet';
|
701 | return `rgba(${Math.round(RGBA[0] * 255)}, ${Math.round(
|
702 | RGBA[1] * 255
|
703 | )}, ${Math.round(RGBA[2] * 255)}, ${RGBA[3]})`;
|
704 | }
|
705 |
|
706 | export function toLinearSpace(
|
707 | RGBA: ParsedColorArray,
|
708 | gamma = 2.2
|
709 | ): ParsedColorArray {
|
710 | 'worklet';
|
711 | const res = [];
|
712 | for (let i = 0; i < 3; ++i) {
|
713 | res.push(Math.pow(RGBA[i], gamma));
|
714 | }
|
715 | res.push(RGBA[3]);
|
716 | return res as ParsedColorArray;
|
717 | }
|
718 |
|
719 | export function toGammaSpace(
|
720 | RGBA: ParsedColorArray,
|
721 | gamma = 2.2
|
722 | ): ParsedColorArray {
|
723 | 'worklet';
|
724 | const res = [];
|
725 | for (let i = 0; i < 3; ++i) {
|
726 | res.push(Math.pow(RGBA[i], 1 / gamma));
|
727 | }
|
728 | res.push(RGBA[3]);
|
729 | return res as ParsedColorArray;
|
730 | }
|