@planet-matrix/mobius-model 0.4.0 → 0.6.0

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.
Files changed (179) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +134 -21
  3. package/dist/index.js +45 -4
  4. package/dist/index.js.map +186 -11
  5. package/oxlint.config.ts +6 -0
  6. package/package.json +16 -10
  7. package/src/abort/README.md +92 -0
  8. package/src/abort/abort-manager.ts +278 -0
  9. package/src/abort/abort-signal-listener-manager.ts +81 -0
  10. package/src/abort/index.ts +2 -0
  11. package/src/basic/README.md +69 -117
  12. package/src/basic/enhance.ts +10 -0
  13. package/src/basic/function.ts +81 -62
  14. package/src/basic/index.ts +2 -0
  15. package/src/basic/is.ts +152 -71
  16. package/src/basic/object.ts +82 -0
  17. package/src/basic/promise.ts +29 -8
  18. package/src/basic/string.ts +2 -33
  19. package/src/color/README.md +105 -0
  20. package/src/color/index.ts +3 -0
  21. package/src/color/internal.ts +42 -0
  22. package/src/color/rgb/analyze.ts +236 -0
  23. package/src/color/rgb/construct.ts +130 -0
  24. package/src/color/rgb/convert.ts +227 -0
  25. package/src/color/rgb/derive.ts +303 -0
  26. package/src/color/rgb/index.ts +6 -0
  27. package/src/color/rgb/internal.ts +208 -0
  28. package/src/color/rgb/parse.ts +302 -0
  29. package/src/color/rgb/serialize.ts +144 -0
  30. package/src/color/types.ts +57 -0
  31. package/src/color/xyz/analyze.ts +80 -0
  32. package/src/color/xyz/construct.ts +19 -0
  33. package/src/color/xyz/convert.ts +71 -0
  34. package/src/color/xyz/index.ts +3 -0
  35. package/src/color/xyz/internal.ts +23 -0
  36. package/src/css/README.md +93 -0
  37. package/src/css/class.ts +559 -0
  38. package/src/css/index.ts +1 -0
  39. package/src/encoding/README.md +92 -0
  40. package/src/encoding/base64.ts +107 -0
  41. package/src/encoding/index.ts +1 -0
  42. package/src/environment/README.md +97 -0
  43. package/src/environment/basic.ts +26 -0
  44. package/src/environment/device.ts +311 -0
  45. package/src/environment/feature.ts +285 -0
  46. package/src/environment/geo.ts +337 -0
  47. package/src/environment/index.ts +7 -0
  48. package/src/environment/runtime.ts +400 -0
  49. package/src/environment/snapshot.ts +60 -0
  50. package/src/environment/variable.ts +239 -0
  51. package/src/event/README.md +90 -0
  52. package/src/event/class-event-proxy.ts +228 -0
  53. package/src/event/common.ts +19 -0
  54. package/src/event/event-manager.ts +203 -0
  55. package/src/event/index.ts +4 -0
  56. package/src/event/instance-event-proxy.ts +186 -0
  57. package/src/event/internal.ts +24 -0
  58. package/src/exception/README.md +96 -0
  59. package/src/exception/browser.ts +219 -0
  60. package/src/exception/index.ts +4 -0
  61. package/src/exception/nodejs.ts +169 -0
  62. package/src/exception/normalize.ts +106 -0
  63. package/src/exception/types.ts +99 -0
  64. package/src/identifier/README.md +92 -0
  65. package/src/identifier/id.ts +119 -0
  66. package/src/identifier/index.ts +2 -0
  67. package/src/identifier/uuid.ts +187 -0
  68. package/src/index.ts +18 -1
  69. package/src/log/README.md +79 -0
  70. package/src/log/index.ts +5 -0
  71. package/src/log/log-emitter.ts +72 -0
  72. package/src/log/log-record.ts +10 -0
  73. package/src/log/log-scheduler.ts +74 -0
  74. package/src/log/log-type.ts +8 -0
  75. package/src/log/logger.ts +543 -0
  76. package/src/orchestration/README.md +89 -0
  77. package/src/orchestration/coordination/barrier.ts +214 -0
  78. package/src/orchestration/coordination/count-down-latch.ts +215 -0
  79. package/src/orchestration/coordination/errors.ts +98 -0
  80. package/src/orchestration/coordination/index.ts +16 -0
  81. package/src/orchestration/coordination/internal/wait-constraints.ts +95 -0
  82. package/src/orchestration/coordination/internal/wait-queue.ts +109 -0
  83. package/src/orchestration/coordination/keyed-lock.ts +168 -0
  84. package/src/orchestration/coordination/mutex.ts +257 -0
  85. package/src/orchestration/coordination/permit.ts +127 -0
  86. package/src/orchestration/coordination/read-write-lock.ts +444 -0
  87. package/src/orchestration/coordination/semaphore.ts +280 -0
  88. package/src/orchestration/index.ts +1 -0
  89. package/src/random/README.md +78 -0
  90. package/src/random/index.ts +1 -0
  91. package/src/random/string.ts +35 -0
  92. package/src/reactor/README.md +4 -0
  93. package/src/reactor/reactor-core/primitive.ts +9 -9
  94. package/src/reactor/reactor-core/reactive-system.ts +5 -5
  95. package/src/singleton/README.md +79 -0
  96. package/src/singleton/factory.ts +55 -0
  97. package/src/singleton/index.ts +2 -0
  98. package/src/singleton/manager.ts +204 -0
  99. package/src/storage/README.md +107 -0
  100. package/src/storage/index.ts +1 -0
  101. package/src/storage/table.ts +449 -0
  102. package/src/timer/README.md +86 -0
  103. package/src/timer/expiration/expiration-manager.ts +594 -0
  104. package/src/timer/expiration/index.ts +3 -0
  105. package/src/timer/expiration/min-heap.ts +208 -0
  106. package/src/timer/expiration/remaining-manager.ts +241 -0
  107. package/src/timer/index.ts +1 -0
  108. package/src/type/README.md +54 -307
  109. package/src/type/class.ts +2 -2
  110. package/src/type/index.ts +14 -14
  111. package/src/type/is.ts +265 -2
  112. package/src/type/object.ts +37 -0
  113. package/src/type/string.ts +7 -2
  114. package/src/type/tuple.ts +6 -6
  115. package/src/type/union.ts +16 -0
  116. package/src/web/README.md +77 -0
  117. package/src/web/capture.ts +35 -0
  118. package/src/web/clipboard.ts +97 -0
  119. package/src/web/dom.ts +117 -0
  120. package/src/web/download.ts +16 -0
  121. package/src/web/event.ts +46 -0
  122. package/src/web/index.ts +10 -0
  123. package/src/web/local-storage.ts +113 -0
  124. package/src/web/location.ts +28 -0
  125. package/src/web/permission.ts +172 -0
  126. package/src/web/script-loader.ts +432 -0
  127. package/tests/unit/abort/abort-manager.spec.ts +225 -0
  128. package/tests/unit/abort/abort-signal-listener-manager.spec.ts +62 -0
  129. package/tests/unit/basic/array.spec.ts +1 -1
  130. package/tests/unit/basic/object.spec.ts +32 -1
  131. package/tests/unit/basic/stream.spec.ts +1 -1
  132. package/tests/unit/basic/string.spec.ts +0 -9
  133. package/tests/unit/color/rgb/analyze.spec.ts +110 -0
  134. package/tests/unit/color/rgb/construct.spec.ts +56 -0
  135. package/tests/unit/color/rgb/convert.spec.ts +60 -0
  136. package/tests/unit/color/rgb/derive.spec.ts +103 -0
  137. package/tests/unit/color/rgb/parse.spec.ts +66 -0
  138. package/tests/unit/color/rgb/serialize.spec.ts +46 -0
  139. package/tests/unit/color/xyz/analyze.spec.ts +33 -0
  140. package/tests/unit/color/xyz/construct.spec.ts +10 -0
  141. package/tests/unit/color/xyz/convert.spec.ts +18 -0
  142. package/tests/unit/css/class.spec.ts +157 -0
  143. package/tests/unit/encoding/base64.spec.ts +40 -0
  144. package/tests/unit/environment/basic.spec.ts +20 -0
  145. package/tests/unit/environment/device.spec.ts +146 -0
  146. package/tests/unit/environment/feature.spec.ts +388 -0
  147. package/tests/unit/environment/geo.spec.ts +111 -0
  148. package/tests/unit/environment/runtime.spec.ts +364 -0
  149. package/tests/unit/environment/snapshot.spec.ts +4 -0
  150. package/tests/unit/environment/variable.spec.ts +190 -0
  151. package/tests/unit/event/class-event-proxy.spec.ts +225 -0
  152. package/tests/unit/event/event-manager.spec.ts +246 -0
  153. package/tests/unit/event/instance-event-proxy.spec.ts +187 -0
  154. package/tests/unit/exception/browser.spec.ts +213 -0
  155. package/tests/unit/exception/nodejs.spec.ts +144 -0
  156. package/tests/unit/exception/normalize.spec.ts +57 -0
  157. package/tests/unit/identifier/id.spec.ts +71 -0
  158. package/tests/unit/identifier/uuid.spec.ts +85 -0
  159. package/tests/unit/log/log-emitter.spec.ts +33 -0
  160. package/tests/unit/log/log-scheduler.spec.ts +40 -0
  161. package/tests/unit/log/log-type.spec.ts +7 -0
  162. package/tests/unit/log/logger.spec.ts +222 -0
  163. package/tests/unit/orchestration/coordination/barrier.spec.ts +96 -0
  164. package/tests/unit/orchestration/coordination/count-down-latch.spec.ts +63 -0
  165. package/tests/unit/orchestration/coordination/errors.spec.ts +29 -0
  166. package/tests/unit/orchestration/coordination/keyed-lock.spec.ts +109 -0
  167. package/tests/unit/orchestration/coordination/mutex.spec.ts +132 -0
  168. package/tests/unit/orchestration/coordination/permit.spec.ts +43 -0
  169. package/tests/unit/orchestration/coordination/read-write-lock.spec.ts +154 -0
  170. package/tests/unit/orchestration/coordination/semaphore.spec.ts +135 -0
  171. package/tests/unit/random/string.spec.ts +11 -0
  172. package/tests/unit/reactor/alien-signals-effect.spec.ts +11 -10
  173. package/tests/unit/reactor/preact-signal.spec.ts +1 -2
  174. package/tests/unit/singleton/singleton.spec.ts +49 -0
  175. package/tests/unit/storage/table.spec.ts +620 -0
  176. package/tests/unit/timer/expiration/expiration-manager.spec.ts +464 -0
  177. package/tests/unit/timer/expiration/min-heap.spec.ts +71 -0
  178. package/tests/unit/timer/expiration/remaining-manager.spec.ts +234 -0
  179. package/.oxlintrc.json +0 -5
@@ -0,0 +1,227 @@
1
+ import {
2
+ internalRoundColorFloat,
3
+ } from "../internal.ts"
4
+ import {
5
+ internalGetLinearRgbChannelBySrgbChannel,
6
+ internalGetSrgbChannelByLinearRgbChannel,
7
+ internalNormalizeHslColorValue,
8
+ internalNormalizeHsvColorValue,
9
+ internalNormalizeLinearRgbColorValue,
10
+ internalNormalizeSrgbColorValue,
11
+ } from "./internal.ts"
12
+
13
+ import type {
14
+ HslColorValue,
15
+ HsvColorValue,
16
+ LinearRgbColorValue,
17
+ SrgbColorValue,
18
+ } from "../types.ts"
19
+
20
+ const internalGetHueByNormalizedRgbChannels = (red: number, green: number, blue: number, delta: number, max: number): number => {
21
+ if (delta === 0) {
22
+ return 0
23
+ }
24
+
25
+ let hue = 0
26
+
27
+ if (max === red) {
28
+ hue = 60 * (((green - blue) / delta) % 6)
29
+ } else if (max === green) {
30
+ hue = 60 * (((blue - red) / delta) + 2)
31
+ } else {
32
+ hue = 60 * (((red - green) / delta) + 4)
33
+ }
34
+
35
+ if (hue < 0) {
36
+ return hue + 360
37
+ }
38
+
39
+ return hue
40
+ }
41
+ const internalGetNormalizedRgbChannelsByHue = (hue: number, chroma: number): { red: number, green: number, blue: number } => {
42
+ const segment = hue / 60
43
+ const secondary = chroma * (1 - Math.abs((segment % 2) - 1))
44
+
45
+ if (segment >= 0 && segment < 1) {
46
+ return { red: chroma, green: secondary, blue: 0 }
47
+ }
48
+
49
+ if (segment >= 1 && segment < 2) {
50
+ return { red: secondary, green: chroma, blue: 0 }
51
+ }
52
+
53
+ if (segment >= 2 && segment < 3) {
54
+ return { red: 0, green: chroma, blue: secondary }
55
+ }
56
+
57
+ if (segment >= 3 && segment < 4) {
58
+ return { red: 0, green: secondary, blue: chroma }
59
+ }
60
+
61
+ if (segment >= 4 && segment < 5) {
62
+ return { red: secondary, green: 0, blue: chroma }
63
+ }
64
+
65
+ return { red: chroma, green: 0, blue: secondary }
66
+ }
67
+
68
+ /**
69
+ * 将 Linear RGB 颜色值转换为 sRGB 颜色值。
70
+ *
71
+ * @example
72
+ * ```
73
+ * // Expect: { red: 255, green: 0, blue: 0, alpha: 1 }
74
+ * const example1 = linearRgbColorValueToSrgbColorValue({ red: 1, green: 0, blue: 0, alpha: 1 })
75
+ *
76
+ * // Expect: { red: 188, green: 188, blue: 188, alpha: 0.5 }
77
+ * const example2 = linearRgbColorValueToSrgbColorValue({ red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5 })
78
+ * ```
79
+ */
80
+ export const linearRgbColorValueToSrgbColorValue = (color: LinearRgbColorValue): SrgbColorValue => {
81
+ const normalizedColor = internalNormalizeLinearRgbColorValue(color)
82
+
83
+ return internalNormalizeSrgbColorValue({
84
+ red: internalGetSrgbChannelByLinearRgbChannel(normalizedColor.red, "red"),
85
+ green: internalGetSrgbChannelByLinearRgbChannel(normalizedColor.green, "green"),
86
+ blue: internalGetSrgbChannelByLinearRgbChannel(normalizedColor.blue, "blue"),
87
+ alpha: normalizedColor.alpha,
88
+ })
89
+ }
90
+
91
+ /**
92
+ * 将 sRGB 颜色值转换为 Linear RGB 颜色值。
93
+ *
94
+ * @example
95
+ * ```
96
+ * // Expect: { red: 1, green: 0, blue: 0, alpha: 1 }
97
+ * const example1 = srgbColorValueToLinearRgbColorValue({ red: 255, green: 0, blue: 0, alpha: 1 })
98
+ *
99
+ * // Expect: { red: 0.215861, green: 0.215861, blue: 0.215861, alpha: 0.5 }
100
+ * const example2 = srgbColorValueToLinearRgbColorValue({ red: 128, green: 128, blue: 128, alpha: 0.5 })
101
+ * ```
102
+ */
103
+ export const srgbColorValueToLinearRgbColorValue = (color: SrgbColorValue): LinearRgbColorValue => {
104
+ const normalizedColor = internalNormalizeSrgbColorValue(color)
105
+
106
+ return internalNormalizeLinearRgbColorValue({
107
+ red: internalGetLinearRgbChannelBySrgbChannel(normalizedColor.red),
108
+ green: internalGetLinearRgbChannelBySrgbChannel(normalizedColor.green),
109
+ blue: internalGetLinearRgbChannelBySrgbChannel(normalizedColor.blue),
110
+ alpha: normalizedColor.alpha,
111
+ })
112
+ }
113
+
114
+ /**
115
+ * 将 sRGB 颜色值转换为 HSL 颜色值。
116
+ *
117
+ * @example
118
+ * ```
119
+ * // Expect: { hue: 210, saturation: 0.5, lightness: 0.4, alpha: 1 }
120
+ * const example1 = srgbColorValueToHslColorValue({ red: 51, green: 102, blue: 153, alpha: 1 })
121
+ *
122
+ * // Expect: { hue: 0, saturation: 0, lightness: 0.501961, alpha: 1 }
123
+ * const example2 = srgbColorValueToHslColorValue({ red: 128, green: 128, blue: 128, alpha: 1 })
124
+ * ```
125
+ */
126
+ export const srgbColorValueToHslColorValue = (color: SrgbColorValue): HslColorValue => {
127
+ const normalizedColor = internalNormalizeSrgbColorValue(color)
128
+ const red = normalizedColor.red / 255
129
+ const green = normalizedColor.green / 255
130
+ const blue = normalizedColor.blue / 255
131
+ const max = Math.max(red, green, blue)
132
+ const min = Math.min(red, green, blue)
133
+ const delta = max - min
134
+ const lightness = (max + min) / 2
135
+ const saturation = delta === 0 ? 0 : delta / (1 - Math.abs((2 * lightness) - 1))
136
+ const hue = internalGetHueByNormalizedRgbChannels(red, green, blue, delta, max)
137
+
138
+ return internalNormalizeHslColorValue({
139
+ hue: internalRoundColorFloat(hue),
140
+ saturation: internalRoundColorFloat(saturation),
141
+ lightness: internalRoundColorFloat(lightness),
142
+ alpha: normalizedColor.alpha,
143
+ })
144
+ }
145
+
146
+ /**
147
+ * 将 HSL 颜色值转换为 sRGB 颜色值。
148
+ *
149
+ * @example
150
+ * ```
151
+ * // Expect: { red: 51, green: 102, blue: 153, alpha: 1 }
152
+ * const example1 = hslColorValueToSrgbColorValue({ hue: 210, saturation: 0.5, lightness: 0.4, alpha: 1 })
153
+ *
154
+ * // Expect: { red: 128, green: 128, blue: 128, alpha: 1 }
155
+ * const example2 = hslColorValueToSrgbColorValue({ hue: 0, saturation: 0, lightness: 0.501961, alpha: 1 })
156
+ * ```
157
+ */
158
+ export const hslColorValueToSrgbColorValue = (color: HslColorValue): SrgbColorValue => {
159
+ const normalizedColor = internalNormalizeHslColorValue(color)
160
+ const chroma = (1 - Math.abs((2 * normalizedColor.lightness) - 1)) * normalizedColor.saturation
161
+ const channels = internalGetNormalizedRgbChannelsByHue(normalizedColor.hue, chroma)
162
+ const match = normalizedColor.lightness - (chroma / 2)
163
+
164
+ return internalNormalizeSrgbColorValue({
165
+ red: Math.round((channels.red + match) * 255),
166
+ green: Math.round((channels.green + match) * 255),
167
+ blue: Math.round((channels.blue + match) * 255),
168
+ alpha: normalizedColor.alpha,
169
+ })
170
+ }
171
+
172
+ /**
173
+ * 将 sRGB 颜色值转换为 HSV 颜色值。
174
+ *
175
+ * @example
176
+ * ```
177
+ * // Expect: { hue: 210, saturation: 0.666667, value: 0.6, alpha: 1 }
178
+ * const example1 = srgbColorValueToHsvColorValue({ red: 51, green: 102, blue: 153, alpha: 1 })
179
+ *
180
+ * // Expect: { hue: 0, saturation: 0, value: 0.501961, alpha: 1 }
181
+ * const example2 = srgbColorValueToHsvColorValue({ red: 128, green: 128, blue: 128, alpha: 1 })
182
+ * ```
183
+ */
184
+ export const srgbColorValueToHsvColorValue = (color: SrgbColorValue): HsvColorValue => {
185
+ const normalizedColor = internalNormalizeSrgbColorValue(color)
186
+ const red = normalizedColor.red / 255
187
+ const green = normalizedColor.green / 255
188
+ const blue = normalizedColor.blue / 255
189
+ const max = Math.max(red, green, blue)
190
+ const min = Math.min(red, green, blue)
191
+ const delta = max - min
192
+ const saturation = max === 0 ? 0 : delta / max
193
+ const hue = internalGetHueByNormalizedRgbChannels(red, green, blue, delta, max)
194
+
195
+ return internalNormalizeHsvColorValue({
196
+ hue: internalRoundColorFloat(hue),
197
+ saturation: internalRoundColorFloat(saturation),
198
+ value: internalRoundColorFloat(max),
199
+ alpha: normalizedColor.alpha,
200
+ })
201
+ }
202
+
203
+ /**
204
+ * 将 HSV 颜色值转换为 sRGB 颜色值。
205
+ *
206
+ * @example
207
+ * ```
208
+ * // Expect: { red: 51, green: 102, blue: 153, alpha: 1 }
209
+ * const example1 = hsvColorValueToSrgbColorValue({ hue: 210, saturation: 0.666667, value: 0.6, alpha: 1 })
210
+ *
211
+ * // Expect: { red: 128, green: 128, blue: 128, alpha: 1 }
212
+ * const example2 = hsvColorValueToSrgbColorValue({ hue: 0, saturation: 0, value: 0.501961, alpha: 1 })
213
+ * ```
214
+ */
215
+ export const hsvColorValueToSrgbColorValue = (color: HsvColorValue): SrgbColorValue => {
216
+ const normalizedColor = internalNormalizeHsvColorValue(color)
217
+ const chroma = normalizedColor.value * normalizedColor.saturation
218
+ const channels = internalGetNormalizedRgbChannelsByHue(normalizedColor.hue, chroma)
219
+ const match = normalizedColor.value - chroma
220
+
221
+ return internalNormalizeSrgbColorValue({
222
+ red: Math.round((channels.red + match) * 255),
223
+ green: Math.round((channels.green + match) * 255),
224
+ blue: Math.round((channels.blue + match) * 255),
225
+ alpha: normalizedColor.alpha,
226
+ })
227
+ }
@@ -0,0 +1,303 @@
1
+ import {
2
+ createLinearRgbColorValue,
3
+ createSrgbColorValue,
4
+ } from "./construct.ts"
5
+ import {
6
+ internalAssertColorUnit,
7
+ internalRoundColorFloat,
8
+ } from "../internal.ts"
9
+ import {
10
+ linearRgbColorValueToSrgbColorValue,
11
+ srgbColorValueToLinearRgbColorValue,
12
+ } from "./convert.ts"
13
+
14
+ import type {
15
+ LinearRgbColorValue,
16
+ SrgbColorValue,
17
+ } from "../types.ts"
18
+
19
+ const internalOpaqueBlackLinearRgbColorValue: LinearRgbColorValue = { red: 0, green: 0, blue: 0, alpha: 1 }
20
+ const internalOpaqueWhiteLinearRgbColorValue: LinearRgbColorValue = { red: 1, green: 1, blue: 1, alpha: 1 }
21
+ const internalOpaqueGrayLinearRgbColorValue: LinearRgbColorValue = { red: 0.5, green: 0.5, blue: 0.5, alpha: 1 }
22
+
23
+ const internalMixNumber = (first: number, second: number, weight: number): number => {
24
+ return internalRoundColorFloat((first * (1 - weight)) + (second * weight))
25
+ }
26
+ const internalCompositeLinearRgbChannels = (foreground: number, background: number, foregroundAlpha: number, backgroundAlpha: number, outputAlpha: number): number => {
27
+ if (outputAlpha === 0) {
28
+ return 0
29
+ }
30
+
31
+ return internalRoundColorFloat(((foreground * foregroundAlpha) + (background * backgroundAlpha * (1 - foregroundAlpha))) / outputAlpha)
32
+ }
33
+ const internalMixSrgbColorValueWithLinearReference = (color: SrgbColorValue, referenceColor: LinearRgbColorValue, amount: number): SrgbColorValue => {
34
+ internalAssertColorUnit(amount, "amount")
35
+ const normalizedColor = createSrgbColorValue(color)
36
+
37
+ return linearRgbColorValueToSrgbColorValue(mixLinearRgbColorValues(
38
+ srgbColorValueToLinearRgbColorValue(normalizedColor),
39
+ referenceColor,
40
+ amount,
41
+ ))
42
+ }
43
+
44
+ /**
45
+ * 在 Linear RGB 层混合两个颜色值。
46
+ *
47
+ * `weight` 表示第二个颜色值的占比。
48
+ *
49
+ * @example
50
+ * ```
51
+ * // Expect: { red: 0.5, green: 0, blue: 0.5, alpha: 1 }
52
+ * const example1 = mixLinearRgbColorValues(
53
+ * { red: 1, green: 0, blue: 0, alpha: 1 },
54
+ * { red: 0, green: 0, blue: 1, alpha: 1 },
55
+ * 0.5,
56
+ * )
57
+ *
58
+ * // Expect: { red: 0.75, green: 0.75, blue: 0.75, alpha: 1 }
59
+ * const example2 = mixLinearRgbColorValues(
60
+ * { red: 1, green: 1, blue: 1, alpha: 1 },
61
+ * { red: 0, green: 0, blue: 0, alpha: 1 },
62
+ * 0.25,
63
+ * )
64
+ * ```
65
+ */
66
+ export const mixLinearRgbColorValues = (first: LinearRgbColorValue, second: LinearRgbColorValue, weight = 0.5): LinearRgbColorValue => {
67
+ internalAssertColorUnit(weight, "weight")
68
+ const normalizedFirst = createLinearRgbColorValue(first)
69
+ const normalizedSecond = createLinearRgbColorValue(second)
70
+
71
+ return createLinearRgbColorValue({
72
+ red: internalMixNumber(normalizedFirst.red, normalizedSecond.red, weight),
73
+ green: internalMixNumber(normalizedFirst.green, normalizedSecond.green, weight),
74
+ blue: internalMixNumber(normalizedFirst.blue, normalizedSecond.blue, weight),
75
+ alpha: internalMixNumber(normalizedFirst.alpha, normalizedSecond.alpha, weight),
76
+ })
77
+ }
78
+
79
+ /**
80
+ * 在 sRGB 层混合两个颜色值。
81
+ *
82
+ * 该函数会沿合法路径 `sRGB -> Linear RGB -> mix -> sRGB` 计算。
83
+ *
84
+ * @example
85
+ * ```
86
+ * // Expect: { red: 188, green: 0, blue: 188, alpha: 1 }
87
+ * const example1 = mixSrgbColorValues(
88
+ * { red: 255, green: 0, blue: 0, alpha: 1 },
89
+ * { red: 0, green: 0, blue: 255, alpha: 1 },
90
+ * 0.5,
91
+ * )
92
+ *
93
+ * // Expect: { red: 255, green: 188, blue: 188, alpha: 1 }
94
+ * const example2 = mixSrgbColorValues(
95
+ * { red: 255, green: 0, blue: 0, alpha: 1 },
96
+ * { red: 255, green: 255, blue: 255, alpha: 1 },
97
+ * 0.5,
98
+ * )
99
+ * ```
100
+ */
101
+ export const mixSrgbColorValues = (first: SrgbColorValue, second: SrgbColorValue, weight = 0.5): SrgbColorValue => {
102
+ internalAssertColorUnit(weight, "weight")
103
+ const normalizedFirst = createSrgbColorValue(first)
104
+ const normalizedSecond = createSrgbColorValue(second)
105
+ const mixedLinearRgbColorValue = mixLinearRgbColorValues(
106
+ srgbColorValueToLinearRgbColorValue(normalizedFirst),
107
+ srgbColorValueToLinearRgbColorValue(normalizedSecond),
108
+ weight,
109
+ )
110
+
111
+ return linearRgbColorValueToSrgbColorValue(mixedLinearRgbColorValue)
112
+ }
113
+
114
+ /**
115
+ * 将一个 Linear RGB 前景色合成到另一个 Linear RGB 背景色之上。
116
+ *
117
+ * 该函数在支线核心计算层直接执行 alpha 合成。
118
+ *
119
+ * @example
120
+ * ```
121
+ * // Expect: { red: 0.5, green: 0.5, blue: 1, alpha: 1 }
122
+ * const example1 = compositeLinearRgbColorValueOverBackground(
123
+ * { red: 1, green: 1, blue: 1, alpha: 0.5 },
124
+ * { red: 0, green: 0, blue: 1, alpha: 1 },
125
+ * )
126
+ *
127
+ * // Expect: { red: 1, green: 0, blue: 0, alpha: 1 }
128
+ * const example2 = compositeLinearRgbColorValueOverBackground(
129
+ * { red: 1, green: 0, blue: 0, alpha: 1 },
130
+ * { red: 0, green: 0, blue: 1, alpha: 1 },
131
+ * )
132
+ * ```
133
+ */
134
+ export const compositeLinearRgbColorValueOverBackground = (foreground: LinearRgbColorValue, background: LinearRgbColorValue): LinearRgbColorValue => {
135
+ const normalizedForeground = createLinearRgbColorValue(foreground)
136
+ const normalizedBackground = createLinearRgbColorValue(background)
137
+ const outputAlpha = internalRoundColorFloat(
138
+ normalizedForeground.alpha + (normalizedBackground.alpha * (1 - normalizedForeground.alpha)),
139
+ )
140
+
141
+ return createLinearRgbColorValue({
142
+ red: internalCompositeLinearRgbChannels(
143
+ normalizedForeground.red,
144
+ normalizedBackground.red,
145
+ normalizedForeground.alpha,
146
+ normalizedBackground.alpha,
147
+ outputAlpha,
148
+ ),
149
+ green: internalCompositeLinearRgbChannels(
150
+ normalizedForeground.green,
151
+ normalizedBackground.green,
152
+ normalizedForeground.alpha,
153
+ normalizedBackground.alpha,
154
+ outputAlpha,
155
+ ),
156
+ blue: internalCompositeLinearRgbChannels(
157
+ normalizedForeground.blue,
158
+ normalizedBackground.blue,
159
+ normalizedForeground.alpha,
160
+ normalizedBackground.alpha,
161
+ outputAlpha,
162
+ ),
163
+ alpha: outputAlpha,
164
+ })
165
+ }
166
+
167
+ /**
168
+ * 将一个 sRGB 前景色沿合法路径合成到另一个 sRGB 背景色之上。
169
+ *
170
+ * 该函数会沿合法路径 `sRGB -> Linear RGB -> composite -> sRGB` 计算。
171
+ *
172
+ * @example
173
+ * ```
174
+ * // Expect: { red: 188, green: 188, blue: 255, alpha: 1 }
175
+ * const example1 = compositeSrgbColorValueOverBackground(
176
+ * { red: 255, green: 255, blue: 255, alpha: 0.5 },
177
+ * { red: 0, green: 0, blue: 255, alpha: 1 },
178
+ * )
179
+ *
180
+ * // Expect: { red: 255, green: 0, blue: 0, alpha: 1 }
181
+ * const example2 = compositeSrgbColorValueOverBackground(
182
+ * { red: 255, green: 0, blue: 0, alpha: 1 },
183
+ * { red: 0, green: 0, blue: 255, alpha: 1 },
184
+ * )
185
+ * ```
186
+ */
187
+ export const compositeSrgbColorValueOverBackground = (foreground: SrgbColorValue, background: SrgbColorValue): SrgbColorValue => {
188
+ const normalizedForeground = createSrgbColorValue(foreground)
189
+ const normalizedBackground = createSrgbColorValue(background)
190
+
191
+ return linearRgbColorValueToSrgbColorValue(compositeLinearRgbColorValueOverBackground(
192
+ srgbColorValueToLinearRgbColorValue(normalizedForeground),
193
+ srgbColorValueToLinearRgbColorValue(normalizedBackground),
194
+ ))
195
+ }
196
+
197
+ /**
198
+ * 调整一个 sRGB 颜色值的透明度。
199
+ *
200
+ * @example
201
+ * ```
202
+ * // Expect: { red: 51, green: 102, blue: 153, alpha: 0.4 }
203
+ * const example1 = fadeSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0.4)
204
+ *
205
+ * // Expect: { red: 51, green: 102, blue: 153, alpha: 0 }
206
+ * const example2 = fadeSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0)
207
+ * ```
208
+ */
209
+ export const fadeSrgbColorValue = (color: SrgbColorValue, alpha: number): SrgbColorValue => {
210
+ internalAssertColorUnit(alpha, "alpha")
211
+ const normalizedColor = createSrgbColorValue(color)
212
+
213
+ return createSrgbColorValue({
214
+ red: normalizedColor.red,
215
+ green: normalizedColor.green,
216
+ blue: normalizedColor.blue,
217
+ alpha,
218
+ })
219
+ }
220
+
221
+ /**
222
+ * 沿合法路径将一个 sRGB 颜色值向白色方向推进。
223
+ *
224
+ * @example
225
+ * ```
226
+ * // Expect: { red: 190, green: 198, blue: 212, alpha: 1 }
227
+ * const example1 = tintSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0.5)
228
+ *
229
+ * // Expect: { red: 51, green: 102, blue: 153, alpha: 1 }
230
+ * const example2 = tintSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0)
231
+ * ```
232
+ */
233
+ export const tintSrgbColorValue = (color: SrgbColorValue, amount: number): SrgbColorValue => {
234
+ return internalMixSrgbColorValueWithLinearReference(color, internalOpaqueWhiteLinearRgbColorValue, amount)
235
+ }
236
+
237
+ /**
238
+ * 沿合法路径将一个 sRGB 颜色值向黑色方向推进。
239
+ *
240
+ * @example
241
+ * ```
242
+ * // Expect: { red: 35, green: 73, blue: 111, alpha: 1 }
243
+ * const example1 = shadeSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0.5)
244
+ *
245
+ * // Expect: { red: 51, green: 102, blue: 153, alpha: 1 }
246
+ * const example2 = shadeSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0)
247
+ * ```
248
+ */
249
+ export const shadeSrgbColorValue = (color: SrgbColorValue, amount: number): SrgbColorValue => {
250
+ return internalMixSrgbColorValueWithLinearReference(color, internalOpaqueBlackLinearRgbColorValue, amount)
251
+ }
252
+
253
+ /**
254
+ * 沿合法路径将一个 sRGB 颜色值向中性灰方向推进。
255
+ *
256
+ * @example
257
+ * ```
258
+ * // Expect: { red: 141, green: 153, blue: 171, alpha: 1 }
259
+ * const example1 = toneSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0.5)
260
+ *
261
+ * // Expect: { red: 51, green: 102, blue: 153, alpha: 1 }
262
+ * const example2 = toneSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0)
263
+ * ```
264
+ */
265
+ export const toneSrgbColorValue = (color: SrgbColorValue, amount: number): SrgbColorValue => {
266
+ return internalMixSrgbColorValueWithLinearReference(color, internalOpaqueGrayLinearRgbColorValue, amount)
267
+ }
268
+
269
+ /**
270
+ * 沿合法路径提高一个 sRGB 颜色值的亮度倾向。
271
+ *
272
+ * 该能力当前等价于向白色混合。
273
+ *
274
+ * @example
275
+ * ```
276
+ * // Expect: { red: 143, green: 160, blue: 186, alpha: 1 }
277
+ * const example1 = lightenSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0.25)
278
+ *
279
+ * // Expect: { red: 51, green: 102, blue: 153, alpha: 1 }
280
+ * const example2 = lightenSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0)
281
+ * ```
282
+ */
283
+ export const lightenSrgbColorValue = (color: SrgbColorValue, amount: number): SrgbColorValue => {
284
+ return tintSrgbColorValue(color, amount)
285
+ }
286
+
287
+ /**
288
+ * 沿合法路径降低一个 sRGB 颜色值的亮度倾向。
289
+ *
290
+ * 该能力当前等价于向黑色混合。
291
+ *
292
+ * @example
293
+ * ```
294
+ * // Expect: { red: 44, green: 89, blue: 134, alpha: 1 }
295
+ * const example1 = darkenSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0.25)
296
+ *
297
+ * // Expect: { red: 51, green: 102, blue: 153, alpha: 1 }
298
+ * const example2 = darkenSrgbColorValue({ red: 51, green: 102, blue: 153, alpha: 1 }, 0)
299
+ * ```
300
+ */
301
+ export const darkenSrgbColorValue = (color: SrgbColorValue, amount: number): SrgbColorValue => {
302
+ return shadeSrgbColorValue(color, amount)
303
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./construct.ts"
2
+ export * from "./convert.ts"
3
+ export * from "./parse.ts"
4
+ export * from "./serialize.ts"
5
+ export * from "./analyze.ts"
6
+ export * from "./derive.ts"