1
1
local config = require (" cyberdream.config" )
2
2
local M = {}
3
3
4
+ --- @alias RGB table {number , number , number }
5
+ --- @alias HSL table {number , number , number }
6
+
4
7
--- Notify the user with a message.
5
8
--- @param message string
6
9
--- @param level ? " info" | " warn" | " error"
@@ -21,6 +24,129 @@ function M.syntax(syntax)
21
24
end
22
25
end
23
26
27
+ --- Convert a hex color to an RGB color.
28
+ --- @param hex string " #rrggbb"
29
+ --- @return RGB
30
+ function M .hex_to_rgb (hex )
31
+ return {
32
+ tonumber (hex :sub (2 , 3 ), 16 ),
33
+ tonumber (hex :sub (4 , 5 ), 16 ),
34
+ tonumber (hex :sub (6 , 7 ), 16 ),
35
+ }
36
+ end
37
+
38
+ --- Convert an RGB color to a hex color.
39
+ --- @param rgb RGB
40
+ --- @return string
41
+ function M .rgb_to_hex (rgb )
42
+ return string.format (" #%02x%02x%02x" , rgb [1 ], rgb [2 ], rgb [3 ])
43
+ end
44
+
45
+ --- Convert an HSL color to RGB.
46
+ --- @param HSL HSL
47
+ --- @return RGB
48
+ function M .hsl_to_rgb (HSL )
49
+ local h , s , l = HSL [1 ] / 360 , HSL [2 ] / 100 , HSL [3 ] / 100
50
+ local r , g , b
51
+
52
+ if s == 0 then
53
+ r , g , b = l , l , l
54
+ else
55
+ local function hue_to_rgb (p , q , t )
56
+ if t < 0 then
57
+ t = t + 1
58
+ end
59
+ if t > 1 then
60
+ t = t - 1
61
+ end
62
+ if t < 1 / 6 then
63
+ return p + (q - p ) * 6 * t
64
+ end
65
+ if t < 1 / 2 then
66
+ return q
67
+ end
68
+ if t < 2 / 3 then
69
+ return p + (q - p ) * (2 / 3 - t ) * 6
70
+ end
71
+ return p
72
+ end
73
+
74
+ local q = l < 0.5 and l * (1 + s ) or l + s - l * s
75
+ local p = 2 * l - q
76
+ r = hue_to_rgb (p , q , h + 1 / 3 )
77
+ g = hue_to_rgb (p , q , h )
78
+ b = hue_to_rgb (p , q , h - 1 / 3 )
79
+ end
80
+
81
+ return { r * 255 , g * 255 , b * 255 }
82
+ end
83
+
84
+ --- Convert an RGB color to HSL.
85
+ --- @param RGB RGB
86
+ --- @return HSL
87
+ function M .rgb_to_hsl (RGB )
88
+ local r , g , b = RGB [1 ] / 255 , RGB [2 ] / 255 , RGB [3 ] / 255
89
+ local max , min = math.max (r , g , b ), math.min (r , g , b )
90
+ local h , s , l
91
+
92
+ l = (max + min ) / 2
93
+
94
+ if max == min then
95
+ h , s = 0 , 0
96
+ else
97
+ local d = max - min
98
+ s = l > 0.5 and d / (2 - max - min ) or d / (max + min )
99
+ if max == r then
100
+ h = (g - b ) / d + (g < b and 6 or 0 )
101
+ elseif max == g then
102
+ h = (b - r ) / d + 2
103
+ elseif max == b then
104
+ h = (r - g ) / d + 4
105
+ end
106
+ h = h / 6
107
+ end
108
+
109
+ return { h * 360 , s * 100 , l * 100 }
110
+ end
111
+
112
+ --- Desaturate an HSL color based on a float. 0 is fully desaturated, 1 is the original color.
113
+ --- @param HSL HSL
114
+ --- @param weight number
115
+ --- @return HSL
116
+ function M .desaturate (HSL , weight )
117
+ weight = weight or 0.5
118
+ HSL [2 ] = HSL [2 ] * weight
119
+ return HSL
120
+ end
121
+
122
+ --- Desaturate a hex color based on a float. 0 is fully desaturated, 1 is the original color.
123
+ function M .desaturate_hex (hex , weight )
124
+ local rgb = M .hex_to_rgb (hex )
125
+ local hsl = M .rgb_to_hsl (rgb )
126
+ local desaturated_hsl = M .desaturate (hsl , weight )
127
+ local desaturated_rgb = M .hsl_to_rgb (desaturated_hsl )
128
+ return string.format (" #%02x%02x%02x" , desaturated_rgb [1 ], desaturated_rgb [2 ], desaturated_rgb [3 ])
129
+ end
130
+
131
+ --- Apply saturation to a table of colors.
132
+ --- @param colors CyberdreamColorLight | CyberdreamColorDefault
133
+ --- @param weight number
134
+ function M .apply_saturation (colors , weight )
135
+ if weight >= 1 then
136
+ return colors
137
+ end
138
+
139
+ if weight < 0 then
140
+ weight = 0
141
+ end
142
+
143
+ local desaturated_colors = {}
144
+ for k , v in pairs (colors ) do
145
+ desaturated_colors [k ] = M .desaturate_hex (v , weight )
146
+ end
147
+ return desaturated_colors
148
+ end
149
+
24
150
--- Load the colorscheme.
25
151
--- @param theme table
26
152
function M .load (theme )
43
169
function M .blend (color1 , color2 , weight )
44
170
weight = weight or 0.5
45
171
46
- local rgb1 = { tonumber (color1 : sub ( 2 , 3 ), 16 ), tonumber ( color1 : sub ( 4 , 5 ), 16 ), tonumber ( color1 : sub ( 6 , 7 ), 16 ) }
47
- local rgb2 = { tonumber (color2 : sub ( 2 , 3 ), 16 ), tonumber ( color2 : sub ( 4 , 5 ), 16 ), tonumber ( color2 : sub ( 6 , 7 ), 16 ) }
172
+ local rgb1 = M . hex_to_rgb (color1 )
173
+ local rgb2 = M . hex_to_rgb (color2 )
48
174
local rgb_blended = {}
49
175
for i = 1 , 3 do
50
176
rgb_blended [i ] = math.floor (rgb1 [i ] * weight + rgb2 [i ] * (1 - weight ))
0 commit comments