@quenty/color3utils 11.18.0 → 11.18.1

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [11.18.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/color3utils@11.18.0...@quenty/color3utils@11.18.1) (2025-04-05)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
12
+
13
+
14
+
15
+
16
+
6
17
  # [11.18.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/color3utils@11.17.2...@quenty/color3utils@11.18.0) (2025-04-02)
7
18
 
8
19
  **Note:** Version bump only for package @quenty/color3utils
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/color3utils",
3
- "version": "11.18.0",
3
+ "version": "11.18.1",
4
4
  "description": "Utility methods for Roblox Color3 values",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -28,12 +28,12 @@
28
28
  "access": "public"
29
29
  },
30
30
  "dependencies": {
31
- "@quenty/blend": "^12.18.0",
32
- "@quenty/loader": "^10.8.0",
33
- "@quenty/maid": "^3.4.0",
34
- "@quenty/math": "^2.7.1",
35
- "@quenty/rx": "^13.17.0",
36
- "@quenty/valueobject": "^13.17.0"
31
+ "@quenty/blend": "^12.18.1",
32
+ "@quenty/loader": "^10.8.1",
33
+ "@quenty/maid": "^3.4.1",
34
+ "@quenty/math": "^2.7.2",
35
+ "@quenty/rx": "^13.17.1",
36
+ "@quenty/valueobject": "^13.17.1"
37
37
  },
38
- "gitHead": "e8ea56930e65322fcffc05a1556d5df988068f0b"
38
+ "gitHead": "78c3ac0ab08dd18085b6e6e6e4f745e76ed99f68"
39
39
  }
@@ -19,7 +19,7 @@ local Color3Utils = {}
19
19
  function Color3Utils.getRelativeLuminance(color: Color3): number
20
20
  local components = { color.R, color.G, color.B }
21
21
  local vals = {}
22
- for i, val in pairs(components) do
22
+ for i, val in components do
23
23
  if val <= 0.03928 then
24
24
  vals[i] = val / 12.92
25
25
  else
@@ -1,3 +1,4 @@
1
+ --!strict
1
2
  --[=[
2
3
  Handles color manipulation in the HpLuv space.
3
4
 
@@ -11,6 +12,8 @@ local require = require(script.Parent.loader).load(script)
11
12
  local LuvUtils = require("LuvUtils")
12
13
  local Math = require("Math")
13
14
 
15
+ export type LUVColor3 = { number }
16
+
14
17
  local LuvColor3Utils = {}
15
18
 
16
19
  --[=[
@@ -20,7 +23,7 @@ local LuvColor3Utils = {}
20
23
  @param t number
21
24
  @return Color3
22
25
  ]=]
23
- function LuvColor3Utils.lerp(color0, color1, t)
26
+ function LuvColor3Utils.lerp(color0: Color3, color1: Color3, t: number): Color3
24
27
  assert(typeof(color0) == "Color3", "Bad color0")
25
28
  assert(typeof(color1) == "Color3", "Bad color0")
26
29
  assert(type(t) == "number", "Bad t")
@@ -34,22 +37,22 @@ function LuvColor3Utils.lerp(color0, color1, t)
34
37
  local l1, u1, v1 = unpack(LuvColor3Utils.fromColor3(color1))
35
38
 
36
39
  local shortest_angle = ((((l1 - l0) % 360) + 540) % 360) - 180
37
- local l = l0 + shortest_angle*t
40
+ local l = l0 + shortest_angle * t
38
41
  local u = Math.lerp(u0, u1, t)
39
42
  local v = Math.lerp(v0, v1, t)
40
43
 
41
- return LuvColor3Utils.toColor3({l, u, v})
44
+ return LuvColor3Utils.toColor3({ l, u, v })
42
45
  end
43
46
  end
44
47
 
45
- function LuvColor3Utils.desaturate(color0, proportion)
48
+ function LuvColor3Utils.desaturate(color0: Color3, proportion: number): Color3
46
49
  local l0, u0, v0 = unpack(LuvColor3Utils.fromColor3(color0))
47
- return LuvColor3Utils.toColor3({l0, u0*math.clamp(1 - proportion, 0, 1), v0})
50
+ return LuvColor3Utils.toColor3({ l0, u0 * math.clamp(1 - proportion, 0, 1), v0 })
48
51
  end
49
52
 
50
- function LuvColor3Utils.darken(color0, proportion)
53
+ function LuvColor3Utils.darken(color0: Color3, proportion: number): Color3
51
54
  local l0, u0, v0 = unpack(LuvColor3Utils.fromColor3(color0))
52
- return LuvColor3Utils.toColor3({l0, u0, v0*math.clamp(1 - proportion, 0, 1)})
55
+ return LuvColor3Utils.toColor3({ l0, u0, v0 * math.clamp(1 - proportion, 0, 1) })
53
56
  end
54
57
 
55
58
  --[=[
@@ -57,10 +60,10 @@ end
57
60
  @param color3 Color3
58
61
  @return { number, number, number }
59
62
  ]=]
60
- function LuvColor3Utils.fromColor3(color3)
63
+ function LuvColor3Utils.fromColor3(color3: Color3): LUVColor3
61
64
  assert(typeof(color3) == "Color3", "Bad color3")
62
65
 
63
- return LuvUtils.rgb_to_hsluv({ color3.r, color3.g, color3.b })
66
+ return LuvUtils.rgb_to_hsluv({ color3.R, color3.G, color3.B })
64
67
  end
65
68
 
66
69
  --[=[
@@ -68,7 +71,7 @@ end
68
71
  @param luv { number, number, number }
69
72
  @return Color3
70
73
  ]=]
71
- function LuvColor3Utils.toColor3(luv)
74
+ function LuvColor3Utils.toColor3(luv: LUVColor3)
72
75
  assert(type(luv) == "table", "Bad luv")
73
76
 
74
77
  local r, g, b = unpack(LuvUtils.hsluv_to_rgb(luv))
@@ -1,3 +1,4 @@
1
+ --!strict
1
2
  --[[
2
3
  Lua implementation of HSLuv and HPLuv color spaces
3
4
  Homepage: https://www.hsluv.org/
@@ -24,18 +25,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25
 
25
26
  local LuvUtils = {}
26
27
 
28
+ export type Tuple = { number }
29
+
27
30
  local hexChars = "0123456789abcdef"
28
31
 
29
- local function distance_line_from_origin(line)
30
- return math.abs(line.intercept) / math.sqrt((line.slope*line.slope) + 1)
32
+ export type Line = {
33
+ slope: number,
34
+ intercept: number,
35
+ }
36
+
37
+ local function distance_line_from_origin(line: Line): number
38
+ return math.abs(line.intercept) / math.sqrt((line.slope * line.slope) + 1)
31
39
  end
32
40
 
33
- local function length_of_ray_until_intersect(theta, line)
41
+ local function length_of_ray_until_intersect(theta: number, line: Line): number
34
42
  return line.intercept / (math.sin(theta) - line.slope * math.cos(theta))
35
43
  end
36
44
 
37
- function LuvUtils.get_bounds(l)
38
- local result = {}
45
+ function LuvUtils.get_bounds(l: number): { Line }
46
+ local result: { Line } = {}
39
47
  local sub2
40
48
  local sub1 = ((l + 16) ^ 3) / 1560896
41
49
  if sub1 > LuvUtils.epsilon then
@@ -55,14 +63,14 @@ function LuvUtils.get_bounds(l)
55
63
  local bottom = (632260 * m3 - 126452 * m2) * sub2 + 126452 * t
56
64
  table.insert(result, {
57
65
  slope = top1 / bottom,
58
- intercept = top2 / bottom
66
+ intercept = top2 / bottom,
59
67
  })
60
68
  end
61
69
  end
62
70
  return result
63
71
  end
64
72
 
65
- function LuvUtils.max_safe_chroma_for_l(l)
73
+ function LuvUtils.max_safe_chroma_for_l(l: number): number
66
74
  local bounds = LuvUtils.get_bounds(l)
67
75
  local min = 1.7976931348623157e+308
68
76
 
@@ -75,7 +83,7 @@ function LuvUtils.max_safe_chroma_for_l(l)
75
83
  return min
76
84
  end
77
85
 
78
- function LuvUtils.max_safe_chroma_for_lh(l, h)
86
+ function LuvUtils.max_safe_chroma_for_lh(l, h: number): number
79
87
  local hrad = h / 360 * math.pi * 2
80
88
  local bounds = LuvUtils.get_bounds(l)
81
89
  local min = 1.7976931348623157e+308
@@ -90,7 +98,7 @@ function LuvUtils.max_safe_chroma_for_lh(l, h)
90
98
  return min
91
99
  end
92
100
 
93
- function LuvUtils.dot_product(a, b)
101
+ function LuvUtils.dot_product(a: Tuple, b: Tuple): number
94
102
  local sum = 0
95
103
  for i = 1, 3 do
96
104
  sum = sum + a[i] * b[i]
@@ -98,7 +106,7 @@ function LuvUtils.dot_product(a, b)
98
106
  return sum
99
107
  end
100
108
 
101
- function LuvUtils.from_linear(c)
109
+ function LuvUtils.from_linear(c: number): number
102
110
  if c <= 0.0031308 then
103
111
  return 12.92 * c
104
112
  else
@@ -106,7 +114,7 @@ function LuvUtils.from_linear(c)
106
114
  end
107
115
  end
108
116
 
109
- function LuvUtils.to_linear(c)
117
+ function LuvUtils.to_linear(c: number): number
110
118
  if c > 0.04045 then
111
119
  return ((c + 0.055) / 1.055) ^ 2.4
112
120
  else
@@ -114,28 +122,28 @@ function LuvUtils.to_linear(c)
114
122
  end
115
123
  end
116
124
 
117
- function LuvUtils.xyz_to_rgb(tuple)
125
+ function LuvUtils.xyz_to_rgb(tuple: Tuple): Tuple
118
126
  return {
119
127
  LuvUtils.from_linear(LuvUtils.dot_product(LuvUtils.m[1], tuple)),
120
128
  LuvUtils.from_linear(LuvUtils.dot_product(LuvUtils.m[2], tuple)),
121
- LuvUtils.from_linear(LuvUtils.dot_product(LuvUtils.m[3], tuple))
129
+ LuvUtils.from_linear(LuvUtils.dot_product(LuvUtils.m[3], tuple)),
122
130
  }
123
131
  end
124
132
 
125
- function LuvUtils.rgb_to_xyz(tuple)
133
+ function LuvUtils.rgb_to_xyz(tuple: Tuple): Tuple
126
134
  local rgbl = {
127
135
  LuvUtils.to_linear(tuple[1]),
128
136
  LuvUtils.to_linear(tuple[2]),
129
- LuvUtils.to_linear(tuple[3])
137
+ LuvUtils.to_linear(tuple[3]),
130
138
  }
131
139
  return {
132
140
  LuvUtils.dot_product(LuvUtils.minv[1], rgbl),
133
141
  LuvUtils.dot_product(LuvUtils.minv[2], rgbl),
134
- LuvUtils.dot_product(LuvUtils.minv[3], rgbl)
142
+ LuvUtils.dot_product(LuvUtils.minv[3], rgbl),
135
143
  }
136
144
  end
137
145
 
138
- function LuvUtils.y_to_l(Y)
146
+ function LuvUtils.y_to_l(Y: number): number
139
147
  if Y <= LuvUtils.epsilon then
140
148
  return Y / LuvUtils.refY * LuvUtils.kappa
141
149
  else
@@ -143,7 +151,7 @@ function LuvUtils.y_to_l(Y)
143
151
  end
144
152
  end
145
153
 
146
- function LuvUtils.l_to_y(L)
154
+ function LuvUtils.l_to_y(L: number): number
147
155
  if L <= 8 then
148
156
  return LuvUtils.refY * L / LuvUtils.kappa
149
157
  else
@@ -151,7 +159,7 @@ function LuvUtils.l_to_y(L)
151
159
  end
152
160
  end
153
161
 
154
- function LuvUtils.xyz_to_luv(tuple)
162
+ function LuvUtils.xyz_to_luv(tuple: Tuple): Tuple
155
163
  local X = tuple[1]
156
164
  local Y = tuple[2]
157
165
  local divider = X + 15 * Y + 3 * tuple[3]
@@ -171,7 +179,7 @@ function LuvUtils.xyz_to_luv(tuple)
171
179
  return { L, 13 * L * (varU - LuvUtils.refU), 13 * L * (varV - LuvUtils.refV) }
172
180
  end
173
181
 
174
- function LuvUtils.luv_to_xyz(tuple)
182
+ function LuvUtils.luv_to_xyz(tuple: Tuple): Tuple
175
183
  local L = tuple[1]
176
184
  local U = tuple[2]
177
185
  local V = tuple[3]
@@ -181,11 +189,11 @@ function LuvUtils.luv_to_xyz(tuple)
181
189
  local varU = U / (13 * L) + LuvUtils.refU
182
190
  local varV = V / (13 * L) + LuvUtils.refV
183
191
  local Y = LuvUtils.l_to_y(L)
184
- local X = 0 - (9 * Y * varU) / ((((varU - 4) * varV) - varU * varV))
192
+ local X = 0 - (9 * Y * varU) / (((varU - 4) * varV) - varU * varV)
185
193
  return { X, Y, (9 * Y - 15 * varV * Y - varV * X) / (3 * varV) }
186
194
  end
187
195
 
188
- function LuvUtils.luv_to_lch(tuple)
196
+ function LuvUtils.luv_to_lch(tuple: Tuple): Tuple
189
197
  local L = tuple[1]
190
198
  local U = tuple[2]
191
199
  local V = tuple[3]
@@ -202,14 +210,14 @@ function LuvUtils.luv_to_lch(tuple)
202
210
  return { L, C, H }
203
211
  end
204
212
 
205
- function LuvUtils.lch_to_luv(tuple)
213
+ function LuvUtils.lch_to_luv(tuple: Tuple): Tuple
206
214
  local L = tuple[1]
207
215
  local C = tuple[2]
208
216
  local Hrad = tuple[3] / 360.0 * 2 * math.pi
209
217
  return { L, math.cos(Hrad) * C, math.sin(Hrad) * C }
210
218
  end
211
219
 
212
- function LuvUtils.hsluv_to_lch(tuple)
220
+ function LuvUtils.hsluv_to_lch(tuple: Tuple): Tuple
213
221
  local H = tuple[1]
214
222
  local S = tuple[2]
215
223
  local L = tuple[3]
@@ -222,7 +230,7 @@ function LuvUtils.hsluv_to_lch(tuple)
222
230
  return { L, LuvUtils.max_safe_chroma_for_lh(L, H) / 100 * S, H }
223
231
  end
224
232
 
225
- function LuvUtils.lch_to_hsluv(tuple)
233
+ function LuvUtils.lch_to_hsluv(tuple: Tuple): Tuple
226
234
  local L = tuple[1]
227
235
  local C = tuple[2]
228
236
  local H = tuple[3]
@@ -237,7 +245,7 @@ function LuvUtils.lch_to_hsluv(tuple)
237
245
  return { H, C / max_chroma * 100, L }
238
246
  end
239
247
 
240
- function LuvUtils.hpluv_to_lch(tuple)
248
+ function LuvUtils.hpluv_to_lch(tuple: Tuple): Tuple
241
249
  local H = tuple[1]
242
250
  local S = tuple[2]
243
251
  local L = tuple[3]
@@ -250,7 +258,7 @@ function LuvUtils.hpluv_to_lch(tuple)
250
258
  return { L, LuvUtils.max_safe_chroma_for_l(L) / 100 * S, H }
251
259
  end
252
260
 
253
- function LuvUtils.lch_to_hpluv(tuple)
261
+ function LuvUtils.lch_to_hpluv(tuple: Tuple): Tuple
254
262
  local L = tuple[1]
255
263
  local C = tuple[2]
256
264
  local H = tuple[3]
@@ -263,69 +271,69 @@ function LuvUtils.lch_to_hpluv(tuple)
263
271
  return { H, C / LuvUtils.max_safe_chroma_for_l(L) * 100, L }
264
272
  end
265
273
 
266
- function LuvUtils.rgb_to_hex(tuple)
267
- local h = "#"
274
+ function LuvUtils.rgb_to_hex(tuple: Tuple): string
275
+ local h: string = "#"
268
276
  for i = 1, 3 do
269
277
  local c = math.floor(tuple[i] * 255 + 0.5)
270
278
  local digit2 = math.fmod(c, 16)
271
279
  local x = (c - digit2) / 16
272
280
  local digit1 = math.floor(x)
273
- h = h .. string.sub(hexChars, digit1 + 1, digit1 + 1)
274
- h = h .. string.sub(hexChars, digit2 + 1, digit2 + 1)
281
+ h ..= string.sub(hexChars, digit1 + 1, digit1 + 1)
282
+ h ..= string.sub(hexChars, digit2 + 1, digit2 + 1)
275
283
  end
276
284
  return h
277
285
  end
278
286
 
279
- function LuvUtils.hex_to_rgb(hex)
287
+ function LuvUtils.hex_to_rgb(hex: string): Tuple
280
288
  hex = string.lower(hex)
281
- local ret = {}
289
+ local ret: Tuple = {}
282
290
  for i = 0, 2 do
283
291
  local char1 = string.sub(hex, i * 2 + 2, i * 2 + 2)
284
292
  local char2 = string.sub(hex, i * 2 + 3, i * 2 + 3)
285
- local digit1 = string.find(hexChars, char1) - 1
286
- local digit2 = string.find(hexChars, char2) - 1
293
+ local digit1 = (string.find(hexChars, char1) :: number) - 1
294
+ local digit2 = (string.find(hexChars, char2) :: number) - 1
287
295
  ret[i + 1] = (digit1 * 16 + digit2) / 255.0
288
296
  end
289
297
  return ret
290
298
  end
291
299
 
292
- function LuvUtils.lch_to_rgb(tuple)
300
+ function LuvUtils.lch_to_rgb(tuple: Tuple): Tuple
293
301
  return LuvUtils.xyz_to_rgb(LuvUtils.luv_to_xyz(LuvUtils.lch_to_luv(tuple)))
294
302
  end
295
303
 
296
- function LuvUtils.rgb_to_lch(tuple)
304
+ function LuvUtils.rgb_to_lch(tuple: Tuple): Tuple
297
305
  return LuvUtils.luv_to_lch(LuvUtils.xyz_to_luv(LuvUtils.rgb_to_xyz(tuple)))
298
306
  end
299
307
 
300
- function LuvUtils.hsluv_to_rgb(tuple)
308
+ function LuvUtils.hsluv_to_rgb(tuple: Tuple): Tuple
301
309
  return LuvUtils.lch_to_rgb(LuvUtils.hsluv_to_lch(tuple))
302
310
  end
303
311
 
304
- function LuvUtils.rgb_to_hsluv(tuple)
312
+ function LuvUtils.rgb_to_hsluv(tuple: Tuple): Tuple
305
313
  return LuvUtils.lch_to_hsluv(LuvUtils.rgb_to_lch(tuple))
306
314
  end
307
315
 
308
- function LuvUtils.hpluv_to_rgb(tuple)
316
+ function LuvUtils.hpluv_to_rgb(tuple: Tuple): Tuple
309
317
  return LuvUtils.lch_to_rgb(LuvUtils.hpluv_to_lch(tuple))
310
318
  end
311
319
 
312
- function LuvUtils.rgb_to_hpluv(tuple)
320
+ function LuvUtils.rgb_to_hpluv(tuple: Tuple): Tuple
313
321
  return LuvUtils.lch_to_hpluv(LuvUtils.rgb_to_lch(tuple))
314
322
  end
315
323
 
316
- function LuvUtils.hsluv_to_hex(tuple)
324
+ function LuvUtils.hsluv_to_hex(tuple: Tuple): string
317
325
  return LuvUtils.rgb_to_hex(LuvUtils.hsluv_to_rgb(tuple))
318
326
  end
319
327
 
320
- function LuvUtils.hpluv_to_hex(tuple)
328
+ function LuvUtils.hpluv_to_hex(tuple: Tuple): string
321
329
  return LuvUtils.rgb_to_hex(LuvUtils.hpluv_to_rgb(tuple))
322
330
  end
323
331
 
324
- function LuvUtils.hex_to_hsluv(s)
332
+ function LuvUtils.hex_to_hsluv(s: string): Tuple
325
333
  return LuvUtils.rgb_to_hsluv(LuvUtils.hex_to_rgb(s))
326
334
  end
327
335
 
328
- function LuvUtils.hex_to_hpluv(s)
336
+ function LuvUtils.hex_to_hpluv(s: string): Tuple
329
337
  return LuvUtils.rgb_to_hpluv(LuvUtils.hex_to_rgb(s))
330
338
  end
331
339