tangled
alpha
login
or
join now
quilling.dev
/
social-app
7
fork
atom
An ATproto social media client -- with an independent Appview.
7
fork
atom
overview
issues
pulls
pipelines
feat: convenience methods
serenity
6 months ago
1462e156
f963e0d8
+79
-21
2 changed files
expand all
collapse all
unified
split
src
alf
util
colors
conversion.ts
index.ts
+18
-21
src/alf/util/colors/conversion.ts
···
1
-
export interface HslColor {
2
-
h: number
3
-
s: number
4
-
l: number
5
-
}
6
-
7
-
export interface RgbColor {
8
-
r: number
9
-
g: number
10
-
b: number
11
-
}
12
-
13
-
export type HexCode = `#${string}` | string
14
15
/**
16
* Converts a hexcode string in the format `"#RRGGBB"` to a `HslColor` object (`{ h: number, s: number, l: number }`).
···
23
const r = parseInt(hex.substring(0, 2), 16) / 255
24
const g = parseInt(hex.substring(2, 4), 16) / 255
25
const b = parseInt(hex.substring(4, 6), 16) / 255
0
26
27
const max = Math.max(r, g, b)
28
const min = Math.min(r, g, b)
···
57
h: h * 360,
58
s: s * 100,
59
l: l * 100,
0
60
}
61
}
62
···
67
* @returns {HexCode} A hexcode string in the format `"#RRGGBB"`. The leading "#" symbol is optional.
68
*/
69
export const hslToHex = (
70
-
{h, s, l}: HslColor,
71
appendSymbol: boolean = true,
72
): HexCode => {
73
h = (h % 360) / 360
···
103
const g = hue(h) * 255
104
const b = hue(h - 1 / 3) * 255
105
106
-
return `${appendSymbol ? '#' : ''}${r.toString(16)}${g.toString(16)}${b.toString(16)}`
107
}
108
109
/**
···
113
* @returns {HexCode} A hexcode string in the format `"#RRGGBB"`. The leading "#" symbol is optional.
114
*/
115
export const rgbToHex = (
116
-
{r, g, b}: RgbColor,
117
appendSymbol: boolean = true,
118
): HexCode => {
119
-
return `${appendSymbol ? '#' : ''}${r.toString(16)}${g.toString(16)}${b.toString(16)}`
120
}
121
122
/**
···
129
const r = parseInt(hex.substring(0, 2), 16) / 255
130
const g = parseInt(hex.substring(2, 4), 16) / 255
131
const b = parseInt(hex.substring(4, 6), 16) / 255
132
-
return {r, g, b}
0
133
}
134
135
/**
···
137
* @param {RgbColor} - An RGB colour object.
138
* @returns {HslColor} A HSL colour object.
139
*/
140
-
export const rgbToHsl = ({r, g, b}: RgbColor): HslColor => {
141
r = r / 255
142
g = g / 255
143
b = b / 255
···
174
h: h * 360,
175
s: s * 100,
176
l: l * 100,
0
177
}
178
}
179
···
182
* @param {HslColor} - A HSL colour object.
183
* @returns {RgbColor} An RGB colour object.
184
*/
185
-
export const hslToRgb = ({h, s, l}: HslColor): RgbColor => {
186
h = (h % 360) / 360
187
s = Math.max(0, Math.min(1, s / 100))
188
l = Math.max(0, Math.min(1, l / 100))
···
216
const g = hue(h) * 255
217
const b = hue(h - 1 / 3) * 255
218
219
-
return {r: Math.round(r), g: Math.round(g), b: Math.round(b)}
0
0
0
0
0
220
}
···
1
+
import {type HexCode, type HslColor, type RgbColor} from '#/alf/util/colors'
0
0
0
0
0
0
0
0
0
0
0
0
2
3
/**
4
* Converts a hexcode string in the format `"#RRGGBB"` to a `HslColor` object (`{ h: number, s: number, l: number }`).
···
11
const r = parseInt(hex.substring(0, 2), 16) / 255
12
const g = parseInt(hex.substring(2, 4), 16) / 255
13
const b = parseInt(hex.substring(4, 6), 16) / 255
14
+
const a = hex.length > 6 ? parseInt(hex.substring(6, 8), 16) / 255 : undefined
15
16
const max = Math.max(r, g, b)
17
const min = Math.min(r, g, b)
···
46
h: h * 360,
47
s: s * 100,
48
l: l * 100,
49
+
a,
50
}
51
}
52
···
57
* @returns {HexCode} A hexcode string in the format `"#RRGGBB"`. The leading "#" symbol is optional.
58
*/
59
export const hslToHex = (
60
+
{h, s, l, a}: HslColor,
61
appendSymbol: boolean = true,
62
): HexCode => {
63
h = (h % 360) / 360
···
93
const g = hue(h) * 255
94
const b = hue(h - 1 / 3) * 255
95
96
+
return `${appendSymbol ? '#' : ''}${r.toString(16)}${g.toString(16)}${b.toString(16)}${a ? a.toString(16) : ''}`
97
}
98
99
/**
···
103
* @returns {HexCode} A hexcode string in the format `"#RRGGBB"`. The leading "#" symbol is optional.
104
*/
105
export const rgbToHex = (
106
+
{r, g, b, a}: RgbColor,
107
appendSymbol: boolean = true,
108
): HexCode => {
109
+
return `${appendSymbol ? '#' : ''}${r.toString(16)}${g.toString(16)}${b.toString(16)}${a ? a.toString(16) : ''}`
110
}
111
112
/**
···
119
const r = parseInt(hex.substring(0, 2), 16) / 255
120
const g = parseInt(hex.substring(2, 4), 16) / 255
121
const b = parseInt(hex.substring(4, 6), 16) / 255
122
+
const a = hex.length > 6 ? parseInt(hex.substring(6, 8), 16) / 255 : undefined
123
+
return {r, g, b, a}
124
}
125
126
/**
···
128
* @param {RgbColor} - An RGB colour object.
129
* @returns {HslColor} A HSL colour object.
130
*/
131
+
export const rgbToHsl = ({r, g, b, a}: RgbColor): HslColor => {
132
r = r / 255
133
g = g / 255
134
b = b / 255
···
165
h: h * 360,
166
s: s * 100,
167
l: l * 100,
168
+
a: a ? (a / 255) * 100 : undefined,
169
}
170
}
171
···
174
* @param {HslColor} - A HSL colour object.
175
* @returns {RgbColor} An RGB colour object.
176
*/
177
+
export const hslToRgb = ({h, s, l, a}: HslColor): RgbColor => {
178
h = (h % 360) / 360
179
s = Math.max(0, Math.min(1, s / 100))
180
l = Math.max(0, Math.min(1, l / 100))
···
208
const g = hue(h) * 255
209
const b = hue(h - 1 / 3) * 255
210
211
+
return {
212
+
r: Math.round(r),
213
+
g: Math.round(g),
214
+
b: Math.round(b),
215
+
a: a ? (a / 100) * 255 : undefined,
216
+
}
217
}
+61
src/alf/util/colors/index.ts
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
import {hexToHsl, hslToHex} from '#/alf/util/colors/conversion'
2
+
3
+
export interface HslColor {
4
+
h: number
5
+
s: number
6
+
l: number
7
+
a?: number
8
+
}
9
+
10
+
export interface RgbColor {
11
+
r: number
12
+
g: number
13
+
b: number
14
+
a?: number
15
+
}
16
+
17
+
export type HexCode = `#${string}` | string
18
+
19
+
export const clamp = (val: number) => {
20
+
return Math.min(1, Math.max(0, val))
21
+
}
22
+
23
+
export const lighten = (
24
+
hex: HexCode,
25
+
amount: number,
26
+
method: 'relative' | undefined = undefined,
27
+
) => {
28
+
const hsl = hexToHsl(hex)
29
+
30
+
if (typeof method !== 'undefined' && method === 'relative') {
31
+
hsl.l += (hsl.l * amount) / 100
32
+
} else {
33
+
hsl.l += amount / 100
34
+
}
35
+
hsl.l = clamp(hsl.l)
36
+
return hslToHex(hsl)
37
+
}
38
+
39
+
export const darken = (
40
+
hex: HexCode,
41
+
amount: number,
42
+
method: 'relative' | undefined = undefined,
43
+
) => {
44
+
const hsl = hexToHsl(hex)
45
+
46
+
if (typeof method !== 'undefined' && method === 'relative') {
47
+
hsl.l -= (hsl.l * amount) / 100
48
+
} else {
49
+
hsl.l -= amount / 100
50
+
}
51
+
hsl.l = clamp(hsl.l)
52
+
return hslToHex(hsl)
53
+
}
54
+
55
+
export const fade = (hex: HexCode, amount: number) => {
56
+
const hsl = hexToHsl(hex)
57
+
58
+
hsl.a = amount / 100
59
+
hsl.a = clamp(hsl.a)
60
+
return hslToHex(hsl)
61
+
}