Skip to content

Commit 0f2c63a

Browse files
committed
feat(core): add hexify pipe to convert various color values to hex-number (0xRRGGBBAA format)
1 parent b3c2071 commit 0f2c63a

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

Diff for: libs/core/src/lib/pipes/hexify.ts

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { DOCUMENT } from '@angular/common';
2+
import { inject, Pipe } from '@angular/core';
3+
4+
@Pipe({ name: 'hexify', pure: true, standalone: true })
5+
export class NgtHexify {
6+
private document = inject(DOCUMENT, { optional: true });
7+
private ctx?: CanvasRenderingContext2D | null;
8+
9+
/**
10+
* transforms a:
11+
* - hex string to a hex number
12+
* - rgb string to a hex number
13+
* - rgba string to a hex number
14+
* - css color string to a hex number
15+
*
16+
* always default to black if failed
17+
* @param value
18+
*/
19+
transform(value: string): number {
20+
if (value == null) return 0x000000;
21+
22+
if (value.startsWith('#')) {
23+
return this.hexStringToNumber(value);
24+
}
25+
26+
if (!this.ctx) {
27+
this.ctx = this.document?.createElement('canvas').getContext('2d');
28+
}
29+
30+
if (!this.ctx) return 0x000000;
31+
32+
this.ctx.fillStyle = value;
33+
const computedValue = this.ctx.fillStyle;
34+
35+
if (computedValue.startsWith('#')) {
36+
return this.hexStringToNumber(computedValue);
37+
}
38+
39+
if (!computedValue.startsWith('rgba')) return 0x000000;
40+
41+
const regex = /rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*(\d*\.?\d+)?\)/;
42+
const match = computedValue.match(regex);
43+
if (!match) return 0x000000;
44+
45+
const r = parseInt(match[1], 10);
46+
const g = parseInt(match[2], 10);
47+
const b = parseInt(match[3], 10);
48+
const a = match[4] ? parseFloat(match[4]) : 1.0;
49+
50+
// Convert the components to hex strings
51+
const hexR = this.componentToHex(r);
52+
const hexG = this.componentToHex(g);
53+
const hexB = this.componentToHex(b);
54+
const hexA = this.componentToHex(Math.round(a * 255));
55+
56+
// Combine the hex components into a single hex string
57+
const hex = `#${hexR}${hexG}${hexB}${hexA}`;
58+
return this.hexStringToNumber(hex);
59+
}
60+
61+
private hexStringToNumber(hexString: string): number {
62+
return parseInt(hexString.replace('#', ''), 16);
63+
}
64+
65+
private componentToHex(component: number): string {
66+
const hex = component.toString(16);
67+
return hex.length === 1 ? '0' + hex : hex;
68+
}
69+
}

0 commit comments

Comments
 (0)