@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.
- package/CHANGELOG.md +32 -0
- package/README.md +134 -21
- package/dist/index.js +45 -4
- package/dist/index.js.map +186 -11
- package/oxlint.config.ts +6 -0
- package/package.json +16 -10
- package/src/abort/README.md +92 -0
- package/src/abort/abort-manager.ts +278 -0
- package/src/abort/abort-signal-listener-manager.ts +81 -0
- package/src/abort/index.ts +2 -0
- package/src/basic/README.md +69 -117
- package/src/basic/enhance.ts +10 -0
- package/src/basic/function.ts +81 -62
- package/src/basic/index.ts +2 -0
- package/src/basic/is.ts +152 -71
- package/src/basic/object.ts +82 -0
- package/src/basic/promise.ts +29 -8
- package/src/basic/string.ts +2 -33
- package/src/color/README.md +105 -0
- package/src/color/index.ts +3 -0
- package/src/color/internal.ts +42 -0
- package/src/color/rgb/analyze.ts +236 -0
- package/src/color/rgb/construct.ts +130 -0
- package/src/color/rgb/convert.ts +227 -0
- package/src/color/rgb/derive.ts +303 -0
- package/src/color/rgb/index.ts +6 -0
- package/src/color/rgb/internal.ts +208 -0
- package/src/color/rgb/parse.ts +302 -0
- package/src/color/rgb/serialize.ts +144 -0
- package/src/color/types.ts +57 -0
- package/src/color/xyz/analyze.ts +80 -0
- package/src/color/xyz/construct.ts +19 -0
- package/src/color/xyz/convert.ts +71 -0
- package/src/color/xyz/index.ts +3 -0
- package/src/color/xyz/internal.ts +23 -0
- package/src/css/README.md +93 -0
- package/src/css/class.ts +559 -0
- package/src/css/index.ts +1 -0
- package/src/encoding/README.md +92 -0
- package/src/encoding/base64.ts +107 -0
- package/src/encoding/index.ts +1 -0
- package/src/environment/README.md +97 -0
- package/src/environment/basic.ts +26 -0
- package/src/environment/device.ts +311 -0
- package/src/environment/feature.ts +285 -0
- package/src/environment/geo.ts +337 -0
- package/src/environment/index.ts +7 -0
- package/src/environment/runtime.ts +400 -0
- package/src/environment/snapshot.ts +60 -0
- package/src/environment/variable.ts +239 -0
- package/src/event/README.md +90 -0
- package/src/event/class-event-proxy.ts +228 -0
- package/src/event/common.ts +19 -0
- package/src/event/event-manager.ts +203 -0
- package/src/event/index.ts +4 -0
- package/src/event/instance-event-proxy.ts +186 -0
- package/src/event/internal.ts +24 -0
- package/src/exception/README.md +96 -0
- package/src/exception/browser.ts +219 -0
- package/src/exception/index.ts +4 -0
- package/src/exception/nodejs.ts +169 -0
- package/src/exception/normalize.ts +106 -0
- package/src/exception/types.ts +99 -0
- package/src/identifier/README.md +92 -0
- package/src/identifier/id.ts +119 -0
- package/src/identifier/index.ts +2 -0
- package/src/identifier/uuid.ts +187 -0
- package/src/index.ts +18 -1
- package/src/log/README.md +79 -0
- package/src/log/index.ts +5 -0
- package/src/log/log-emitter.ts +72 -0
- package/src/log/log-record.ts +10 -0
- package/src/log/log-scheduler.ts +74 -0
- package/src/log/log-type.ts +8 -0
- package/src/log/logger.ts +543 -0
- package/src/orchestration/README.md +89 -0
- package/src/orchestration/coordination/barrier.ts +214 -0
- package/src/orchestration/coordination/count-down-latch.ts +215 -0
- package/src/orchestration/coordination/errors.ts +98 -0
- package/src/orchestration/coordination/index.ts +16 -0
- package/src/orchestration/coordination/internal/wait-constraints.ts +95 -0
- package/src/orchestration/coordination/internal/wait-queue.ts +109 -0
- package/src/orchestration/coordination/keyed-lock.ts +168 -0
- package/src/orchestration/coordination/mutex.ts +257 -0
- package/src/orchestration/coordination/permit.ts +127 -0
- package/src/orchestration/coordination/read-write-lock.ts +444 -0
- package/src/orchestration/coordination/semaphore.ts +280 -0
- package/src/orchestration/index.ts +1 -0
- package/src/random/README.md +78 -0
- package/src/random/index.ts +1 -0
- package/src/random/string.ts +35 -0
- package/src/reactor/README.md +4 -0
- package/src/reactor/reactor-core/primitive.ts +9 -9
- package/src/reactor/reactor-core/reactive-system.ts +5 -5
- package/src/singleton/README.md +79 -0
- package/src/singleton/factory.ts +55 -0
- package/src/singleton/index.ts +2 -0
- package/src/singleton/manager.ts +204 -0
- package/src/storage/README.md +107 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/table.ts +449 -0
- package/src/timer/README.md +86 -0
- package/src/timer/expiration/expiration-manager.ts +594 -0
- package/src/timer/expiration/index.ts +3 -0
- package/src/timer/expiration/min-heap.ts +208 -0
- package/src/timer/expiration/remaining-manager.ts +241 -0
- package/src/timer/index.ts +1 -0
- package/src/type/README.md +54 -307
- package/src/type/class.ts +2 -2
- package/src/type/index.ts +14 -14
- package/src/type/is.ts +265 -2
- package/src/type/object.ts +37 -0
- package/src/type/string.ts +7 -2
- package/src/type/tuple.ts +6 -6
- package/src/type/union.ts +16 -0
- package/src/web/README.md +77 -0
- package/src/web/capture.ts +35 -0
- package/src/web/clipboard.ts +97 -0
- package/src/web/dom.ts +117 -0
- package/src/web/download.ts +16 -0
- package/src/web/event.ts +46 -0
- package/src/web/index.ts +10 -0
- package/src/web/local-storage.ts +113 -0
- package/src/web/location.ts +28 -0
- package/src/web/permission.ts +172 -0
- package/src/web/script-loader.ts +432 -0
- package/tests/unit/abort/abort-manager.spec.ts +225 -0
- package/tests/unit/abort/abort-signal-listener-manager.spec.ts +62 -0
- package/tests/unit/basic/array.spec.ts +1 -1
- package/tests/unit/basic/object.spec.ts +32 -1
- package/tests/unit/basic/stream.spec.ts +1 -1
- package/tests/unit/basic/string.spec.ts +0 -9
- package/tests/unit/color/rgb/analyze.spec.ts +110 -0
- package/tests/unit/color/rgb/construct.spec.ts +56 -0
- package/tests/unit/color/rgb/convert.spec.ts +60 -0
- package/tests/unit/color/rgb/derive.spec.ts +103 -0
- package/tests/unit/color/rgb/parse.spec.ts +66 -0
- package/tests/unit/color/rgb/serialize.spec.ts +46 -0
- package/tests/unit/color/xyz/analyze.spec.ts +33 -0
- package/tests/unit/color/xyz/construct.spec.ts +10 -0
- package/tests/unit/color/xyz/convert.spec.ts +18 -0
- package/tests/unit/css/class.spec.ts +157 -0
- package/tests/unit/encoding/base64.spec.ts +40 -0
- package/tests/unit/environment/basic.spec.ts +20 -0
- package/tests/unit/environment/device.spec.ts +146 -0
- package/tests/unit/environment/feature.spec.ts +388 -0
- package/tests/unit/environment/geo.spec.ts +111 -0
- package/tests/unit/environment/runtime.spec.ts +364 -0
- package/tests/unit/environment/snapshot.spec.ts +4 -0
- package/tests/unit/environment/variable.spec.ts +190 -0
- package/tests/unit/event/class-event-proxy.spec.ts +225 -0
- package/tests/unit/event/event-manager.spec.ts +246 -0
- package/tests/unit/event/instance-event-proxy.spec.ts +187 -0
- package/tests/unit/exception/browser.spec.ts +213 -0
- package/tests/unit/exception/nodejs.spec.ts +144 -0
- package/tests/unit/exception/normalize.spec.ts +57 -0
- package/tests/unit/identifier/id.spec.ts +71 -0
- package/tests/unit/identifier/uuid.spec.ts +85 -0
- package/tests/unit/log/log-emitter.spec.ts +33 -0
- package/tests/unit/log/log-scheduler.spec.ts +40 -0
- package/tests/unit/log/log-type.spec.ts +7 -0
- package/tests/unit/log/logger.spec.ts +222 -0
- package/tests/unit/orchestration/coordination/barrier.spec.ts +96 -0
- package/tests/unit/orchestration/coordination/count-down-latch.spec.ts +63 -0
- package/tests/unit/orchestration/coordination/errors.spec.ts +29 -0
- package/tests/unit/orchestration/coordination/keyed-lock.spec.ts +109 -0
- package/tests/unit/orchestration/coordination/mutex.spec.ts +132 -0
- package/tests/unit/orchestration/coordination/permit.spec.ts +43 -0
- package/tests/unit/orchestration/coordination/read-write-lock.spec.ts +154 -0
- package/tests/unit/orchestration/coordination/semaphore.spec.ts +135 -0
- package/tests/unit/random/string.spec.ts +11 -0
- package/tests/unit/reactor/alien-signals-effect.spec.ts +11 -10
- package/tests/unit/reactor/preact-signal.spec.ts +1 -2
- package/tests/unit/singleton/singleton.spec.ts +49 -0
- package/tests/unit/storage/table.spec.ts +620 -0
- package/tests/unit/timer/expiration/expiration-manager.spec.ts +464 -0
- package/tests/unit/timer/expiration/min-heap.spec.ts +71 -0
- package/tests/unit/timer/expiration/remaining-manager.spec.ts +234 -0
- package/.oxlintrc.json +0 -5
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import {
|
|
2
|
+
internalAssertAlpha,
|
|
3
|
+
internalAssertColorUnit,
|
|
4
|
+
internalAssertFinite,
|
|
5
|
+
internalRoundColorFloat,
|
|
6
|
+
} from "../internal.ts"
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
HslColorValue,
|
|
10
|
+
HsvColorValue,
|
|
11
|
+
LinearRgbColorValue,
|
|
12
|
+
SrgbColorValue,
|
|
13
|
+
} from "../types.ts"
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 匹配模块支持的十六进制颜色字符串格式。
|
|
17
|
+
*/
|
|
18
|
+
export const internalHexPattern: RegExp = /^#?(?:[\da-fA-F]{3}|[\da-fA-F]{4}|[\da-fA-F]{6}|[\da-fA-F]{8})$/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 断言一个 sRGB 通道值是合法的 8 位整数。
|
|
22
|
+
*/
|
|
23
|
+
export const internalAssertByte = (value: number, channelName: string): void => {
|
|
24
|
+
if (Number.isInteger(value) === false || value < 0 || value > 255) {
|
|
25
|
+
throw new RangeError(`Color channel ${channelName} must be an integer between 0 and 255`)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 将色相角度规范化到 `0` 到 `360` 之间,`360` 会被折叠为 `0`。
|
|
31
|
+
*/
|
|
32
|
+
export const internalNormalizeHue = (value: number): number => {
|
|
33
|
+
internalAssertFinite(value, "Color hue")
|
|
34
|
+
|
|
35
|
+
const normalizedValue = value % 360
|
|
36
|
+
if (normalizedValue < 0) {
|
|
37
|
+
return normalizedValue + 360
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return normalizedValue
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 规范化 Linear RGB 颜色值结构。
|
|
45
|
+
*/
|
|
46
|
+
export const internalNormalizeLinearRgbColorValue = (color: LinearRgbColorValue): LinearRgbColorValue => {
|
|
47
|
+
internalAssertFinite(color.red, "Color channel red")
|
|
48
|
+
internalAssertFinite(color.green, "Color channel green")
|
|
49
|
+
internalAssertFinite(color.blue, "Color channel blue")
|
|
50
|
+
internalAssertAlpha(color.alpha)
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
red: color.red,
|
|
54
|
+
green: color.green,
|
|
55
|
+
blue: color.blue,
|
|
56
|
+
alpha: color.alpha,
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 规范化 sRGB 颜色值结构。
|
|
62
|
+
*/
|
|
63
|
+
export const internalNormalizeSrgbColorValue = (color: SrgbColorValue): SrgbColorValue => {
|
|
64
|
+
internalAssertByte(color.red, "red")
|
|
65
|
+
internalAssertByte(color.green, "green")
|
|
66
|
+
internalAssertByte(color.blue, "blue")
|
|
67
|
+
internalAssertAlpha(color.alpha)
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
red: color.red,
|
|
71
|
+
green: color.green,
|
|
72
|
+
blue: color.blue,
|
|
73
|
+
alpha: color.alpha,
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 规范化 HSL 颜色值结构。
|
|
79
|
+
*/
|
|
80
|
+
export const internalNormalizeHslColorValue = (color: HslColorValue): HslColorValue => {
|
|
81
|
+
internalAssertColorUnit(color.saturation, "saturation")
|
|
82
|
+
internalAssertColorUnit(color.lightness, "lightness")
|
|
83
|
+
internalAssertAlpha(color.alpha)
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
hue: internalNormalizeHue(color.hue),
|
|
87
|
+
saturation: internalRoundColorFloat(color.saturation),
|
|
88
|
+
lightness: internalRoundColorFloat(color.lightness),
|
|
89
|
+
alpha: color.alpha,
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 规范化 HSV 颜色值结构。
|
|
95
|
+
*/
|
|
96
|
+
export const internalNormalizeHsvColorValue = (color: HsvColorValue): HsvColorValue => {
|
|
97
|
+
internalAssertColorUnit(color.saturation, "saturation")
|
|
98
|
+
internalAssertColorUnit(color.value, "value")
|
|
99
|
+
internalAssertAlpha(color.alpha)
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
hue: internalNormalizeHue(color.hue),
|
|
103
|
+
saturation: internalRoundColorFloat(color.saturation),
|
|
104
|
+
value: internalRoundColorFloat(color.value),
|
|
105
|
+
alpha: color.alpha,
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 将短格式十六进制颜色扩展为长格式。
|
|
111
|
+
*/
|
|
112
|
+
export const internalExpandShortHex = (input: string): string => {
|
|
113
|
+
return input.split("").map(char => `${char}${char}`).join("")
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 将 8 位通道值格式化为两位十六进制字符串。
|
|
118
|
+
*/
|
|
119
|
+
export const internalFormatHexByte = (value: number): string => {
|
|
120
|
+
return value.toString(16).padStart(2, "0").toUpperCase()
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 将浮点数格式化为适合颜色字符串的紧凑小数字符串。
|
|
125
|
+
*/
|
|
126
|
+
export const internalFormatAlpha = (value: number): string => {
|
|
127
|
+
return Number(value.toFixed(4)).toString()
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 将 `0` 到 `1` 的单位值格式化为百分比数值字符串,不附带 `%` 符号。
|
|
132
|
+
*/
|
|
133
|
+
export const internalFormatPercentUnit = (value: number): string => {
|
|
134
|
+
internalAssertColorUnit(value, "unit")
|
|
135
|
+
return Number((value * 100).toFixed(2)).toString()
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* 将 RGB 字符串通道解析为合法的 8 位通道值。
|
|
140
|
+
*/
|
|
141
|
+
export const internalParseRgbChannel = (input: string, channelName: string): number => {
|
|
142
|
+
const value = Number(input)
|
|
143
|
+
internalAssertByte(value, channelName)
|
|
144
|
+
return value
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* 将百分比字符串解析为 `0` 到 `1` 之间的单位值。
|
|
149
|
+
*/
|
|
150
|
+
export const internalParsePercentUnit = (input: string, channelName: string): number => {
|
|
151
|
+
if (input.endsWith("%") === false) {
|
|
152
|
+
throw new TypeError(`Invalid ${channelName} percentage input`)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return internalRoundColorFloat(Number(input.slice(0, -1)) / 100)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 将 8 位 sRGB 通道值转换为线性光通道值。
|
|
160
|
+
*/
|
|
161
|
+
export const internalGetLinearRgbChannelBySrgbChannel = (value: number): number => {
|
|
162
|
+
internalAssertByte(value, "sRGB")
|
|
163
|
+
const normalizedValue = value / 255
|
|
164
|
+
|
|
165
|
+
if (normalizedValue <= 0.040_45) {
|
|
166
|
+
return internalRoundColorFloat(normalizedValue / 12.92)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return internalRoundColorFloat(((normalizedValue + 0.055) / 1.055) ** 2.4)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* 将线性光通道值转换为 8 位 sRGB 通道值。
|
|
174
|
+
*/
|
|
175
|
+
export const internalGetSrgbChannelByLinearRgbChannel = (value: number, channelName: string): number => {
|
|
176
|
+
internalAssertFinite(value, `Linear RGB channel ${channelName}`)
|
|
177
|
+
|
|
178
|
+
if (value < 0 || value > 1) {
|
|
179
|
+
throw new RangeError(`Linear RGB channel ${channelName} must be between 0 and 1 to convert to sRGB`)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (value <= 0.003_130_8) {
|
|
183
|
+
return Math.round(value * 12.92 * 255)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return Math.round(((1.055 * (value ** (1 / 2.4))) - 0.055) * 255)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* 根据输入字符串稳定生成一个 sRGB 颜色值。
|
|
191
|
+
*/
|
|
192
|
+
export const internalGetStableSrgbColorValueByString = (input: string): SrgbColorValue => {
|
|
193
|
+
let codePointSum = 0
|
|
194
|
+
|
|
195
|
+
for (const char of input) {
|
|
196
|
+
const codePoint = char.codePointAt(0)
|
|
197
|
+
if (codePoint !== undefined) {
|
|
198
|
+
codePointSum = codePointSum + codePoint
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
red: Math.round(Math.abs(Math.sin(codePointSum) * 255)),
|
|
204
|
+
green: Math.round(Math.abs(Math.sin(codePointSum + 1) * 255)),
|
|
205
|
+
blue: Math.round(Math.abs(Math.sin(codePointSum + 2) * 255)),
|
|
206
|
+
alpha: 1,
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { internalAssertAlpha } from "../internal.ts"
|
|
2
|
+
import {
|
|
3
|
+
createHslColorValue,
|
|
4
|
+
createHsvColorValue,
|
|
5
|
+
createSrgbColorValue,
|
|
6
|
+
} from "./construct.ts"
|
|
7
|
+
import {
|
|
8
|
+
hslColorValueToSrgbColorValue,
|
|
9
|
+
hsvColorValueToSrgbColorValue,
|
|
10
|
+
} from "./convert.ts"
|
|
11
|
+
import {
|
|
12
|
+
internalExpandShortHex,
|
|
13
|
+
internalHexPattern,
|
|
14
|
+
internalParsePercentUnit,
|
|
15
|
+
internalParseRgbChannel,
|
|
16
|
+
} from "./internal.ts"
|
|
17
|
+
|
|
18
|
+
import type {
|
|
19
|
+
HslColorValue,
|
|
20
|
+
HsvColorValue,
|
|
21
|
+
SrgbColorValue,
|
|
22
|
+
} from "../types.ts"
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 判断输入是否为合法的十六进制颜色字符串。
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```
|
|
29
|
+
* // Expect: true
|
|
30
|
+
* const example1 = isHexColorString("#F0A")
|
|
31
|
+
*
|
|
32
|
+
* // Expect: false
|
|
33
|
+
* const example2 = isHexColorString("#12")
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export const isHexColorString = (input: string): boolean => {
|
|
37
|
+
return internalHexPattern.test(input.trim())
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 将十六进制颜色字符串解析为 sRGB 颜色值对象。
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```
|
|
45
|
+
* // Expect: { red: 255, green: 0, blue: 170, alpha: 1 }
|
|
46
|
+
* const example1 = hexColorStringToSrgbColorValue("#F0A")
|
|
47
|
+
*
|
|
48
|
+
* // Expect: { red: 17, green: 34, blue: 51, alpha: 0.2667 }
|
|
49
|
+
* const example2 = hexColorStringToSrgbColorValue("#11223344")
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export const hexColorStringToSrgbColorValue = (input: string): SrgbColorValue => {
|
|
53
|
+
const normalizedInput = input.trim()
|
|
54
|
+
if (isHexColorString(normalizedInput) === false) {
|
|
55
|
+
throw new TypeError("Invalid hex color input")
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const hex = normalizedInput.startsWith("#") ? normalizedInput.slice(1) : normalizedInput
|
|
59
|
+
const expandedHex = hex.length === 3 || hex.length === 4 ? internalExpandShortHex(hex) : hex
|
|
60
|
+
const red = Number.parseInt(expandedHex.slice(0, 2), 16)
|
|
61
|
+
const green = Number.parseInt(expandedHex.slice(2, 4), 16)
|
|
62
|
+
const blue = Number.parseInt(expandedHex.slice(4, 6), 16)
|
|
63
|
+
const alpha = expandedHex.length === 8
|
|
64
|
+
? Number((Number.parseInt(expandedHex.slice(6, 8), 16) / 255).toFixed(4))
|
|
65
|
+
: 1
|
|
66
|
+
|
|
67
|
+
return createSrgbColorValue({ red, green, blue, alpha })
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const internalParseRgbParts = (input: string, allowAlpha: boolean): SrgbColorValue => {
|
|
71
|
+
const rgbMatch = /^rgba?\((.*)\)$/i.exec(input)
|
|
72
|
+
if (rgbMatch === null) {
|
|
73
|
+
throw new TypeError("Invalid color string input")
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const partsSource = rgbMatch[1]
|
|
77
|
+
if (partsSource === undefined) {
|
|
78
|
+
throw new TypeError("Invalid color string input")
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const parts = partsSource.split(",").map(part => part.trim())
|
|
82
|
+
if (allowAlpha === true && parts.length !== 4) {
|
|
83
|
+
throw new TypeError("Invalid RGBA color string input")
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (allowAlpha === false && parts.length !== 3) {
|
|
87
|
+
throw new TypeError("Invalid RGB color string input")
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const [redPart = "", greenPart = "", bluePart = "", alphaPart] = parts
|
|
91
|
+
const red = internalParseRgbChannel(redPart, "red")
|
|
92
|
+
const green = internalParseRgbChannel(greenPart, "green")
|
|
93
|
+
const blue = internalParseRgbChannel(bluePart, "blue")
|
|
94
|
+
const alpha = allowAlpha === true ? Number(alphaPart) : 1
|
|
95
|
+
|
|
96
|
+
return createSrgbColorValue({ red, green, blue, alpha })
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 将 `rgb(r, g, b)` 字符串解析为 sRGB 颜色值对象。
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```
|
|
104
|
+
* // Expect: { red: 51, green: 102, blue: 153, alpha: 1 }
|
|
105
|
+
* const example1 = rgbColorStringToSrgbColorValue("rgb(51, 102, 153)")
|
|
106
|
+
*
|
|
107
|
+
* // Expect: { red: 0, green: 0, blue: 0, alpha: 1 }
|
|
108
|
+
* const example2 = rgbColorStringToSrgbColorValue("rgb(0, 0, 0)")
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export const rgbColorStringToSrgbColorValue = (input: string): SrgbColorValue => {
|
|
112
|
+
return internalParseRgbParts(input.trim(), false)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* 将 `rgba(r, g, b, a)` 字符串解析为 sRGB 颜色值对象。
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```
|
|
120
|
+
* // Expect: { red: 51, green: 102, blue: 153, alpha: 0.5 }
|
|
121
|
+
* const example1 = rgbaColorStringToSrgbColorValue("rgba(51, 102, 153, 0.5)")
|
|
122
|
+
*
|
|
123
|
+
* // Expect: { red: 255, green: 255, blue: 255, alpha: 1 }
|
|
124
|
+
* const example2 = rgbaColorStringToSrgbColorValue("rgba(255, 255, 255, 1)")
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export const rgbaColorStringToSrgbColorValue = (input: string): SrgbColorValue => {
|
|
128
|
+
return internalParseRgbParts(input.trim(), true)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const internalParseHslParts = (input: string, allowAlpha: boolean): HslColorValue => {
|
|
132
|
+
const hslMatch = /^hsla?\((.*)\)$/i.exec(input)
|
|
133
|
+
if (hslMatch === null) {
|
|
134
|
+
throw new TypeError("Invalid color string input")
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const partsSource = hslMatch[1]
|
|
138
|
+
if (partsSource === undefined) {
|
|
139
|
+
throw new TypeError("Invalid color string input")
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const parts = partsSource.split(",").map(part => part.trim())
|
|
143
|
+
if (allowAlpha === true && parts.length !== 4) {
|
|
144
|
+
throw new TypeError("Invalid HSLA color string input")
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (allowAlpha === false && parts.length !== 3) {
|
|
148
|
+
throw new TypeError("Invalid HSL color string input")
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const [huePart = "", saturationPart = "", lightnessPart = "", alphaPart] = parts
|
|
152
|
+
const hue = Number(huePart)
|
|
153
|
+
const saturation = internalParsePercentUnit(saturationPart, "saturation")
|
|
154
|
+
const lightness = internalParsePercentUnit(lightnessPart, "lightness")
|
|
155
|
+
const alpha = allowAlpha === true ? Number(alphaPart) : 1
|
|
156
|
+
internalAssertAlpha(alpha)
|
|
157
|
+
|
|
158
|
+
return createHslColorValue({ hue, saturation, lightness, alpha })
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* 将 `hsl(h, s%, l%)` 字符串解析为 HSL 颜色值对象。
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```
|
|
166
|
+
* // Expect: { hue: 210, saturation: 0.5, lightness: 0.4, alpha: 1 }
|
|
167
|
+
* const example1 = hslColorStringToHslColorValue("hsl(210, 50%, 40%)")
|
|
168
|
+
*
|
|
169
|
+
* // Expect: { hue: 330, saturation: 0.5, lightness: 0.4, alpha: 1 }
|
|
170
|
+
* const example2 = hslColorStringToHslColorValue("hsl(-30, 50%, 40%)")
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export const hslColorStringToHslColorValue = (input: string): HslColorValue => {
|
|
174
|
+
return internalParseHslParts(input.trim(), false)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* 将 `hsla(h, s%, l%, a)` 字符串解析为 HSL 颜色值对象。
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```
|
|
182
|
+
* // Expect: { hue: 210, saturation: 0.5, lightness: 0.4, alpha: 0.5 }
|
|
183
|
+
* const example1 = hslaColorStringToHslColorValue("hsla(210, 50%, 40%, 0.5)")
|
|
184
|
+
*
|
|
185
|
+
* // Expect: { hue: 0, saturation: 0, lightness: 1, alpha: 1 }
|
|
186
|
+
* const example2 = hslaColorStringToHslColorValue("hsla(0, 0%, 100%, 1)")
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
export const hslaColorStringToHslColorValue = (input: string): HslColorValue => {
|
|
190
|
+
return internalParseHslParts(input.trim(), true)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const internalParseHsvParts = (input: string, allowAlpha: boolean): HsvColorValue => {
|
|
194
|
+
const hsvMatch = /^hsva?\((.*)\)$/i.exec(input)
|
|
195
|
+
if (hsvMatch === null) {
|
|
196
|
+
throw new TypeError("Invalid color string input")
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const partsSource = hsvMatch[1]
|
|
200
|
+
if (partsSource === undefined) {
|
|
201
|
+
throw new TypeError("Invalid color string input")
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const parts = partsSource.split(",").map(part => part.trim())
|
|
205
|
+
if (allowAlpha === true && parts.length !== 4) {
|
|
206
|
+
throw new TypeError("Invalid HSVA color string input")
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (allowAlpha === false && parts.length !== 3) {
|
|
210
|
+
throw new TypeError("Invalid HSV color string input")
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const [huePart = "", saturationPart = "", valuePart = "", alphaPart] = parts
|
|
214
|
+
const hue = Number(huePart)
|
|
215
|
+
const saturation = internalParsePercentUnit(saturationPart, "saturation")
|
|
216
|
+
const value = internalParsePercentUnit(valuePart, "value")
|
|
217
|
+
const alpha = allowAlpha === true ? Number(alphaPart) : 1
|
|
218
|
+
internalAssertAlpha(alpha)
|
|
219
|
+
|
|
220
|
+
return createHsvColorValue({ hue, saturation, value, alpha })
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* 将 `hsv(h, s%, v%)` 字符串解析为 HSV 颜色值对象。
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```
|
|
228
|
+
* // Expect: { hue: 210, saturation: 0.6667, value: 0.6, alpha: 1 }
|
|
229
|
+
* const example1 = hsvColorStringToHsvColorValue("hsv(210, 66.67%, 60%)")
|
|
230
|
+
*
|
|
231
|
+
* // Expect: { hue: 30, saturation: 0.5, value: 0.6, alpha: 1 }
|
|
232
|
+
* const example2 = hsvColorStringToHsvColorValue("hsv(390, 50%, 60%)")
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
export const hsvColorStringToHsvColorValue = (input: string): HsvColorValue => {
|
|
236
|
+
return internalParseHsvParts(input.trim(), false)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* 将 `hsva(h, s%, v%, a)` 字符串解析为 HSV 颜色值对象。
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```
|
|
244
|
+
* // Expect: { hue: 210, saturation: 0.6667, value: 0.6, alpha: 0.5 }
|
|
245
|
+
* const example1 = hsvaColorStringToHsvColorValue("hsva(210, 66.67%, 60%, 0.5)")
|
|
246
|
+
*
|
|
247
|
+
* // Expect: { hue: 0, saturation: 0, value: 1, alpha: 1 }
|
|
248
|
+
* const example2 = hsvaColorStringToHsvColorValue("hsva(0, 0%, 100%, 1)")
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
export const hsvaColorStringToHsvColorValue = (input: string): HsvColorValue => {
|
|
252
|
+
return internalParseHsvParts(input.trim(), true)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* 将异构颜色字符串归一化为 sRGB 颜色值对象。
|
|
257
|
+
*
|
|
258
|
+
* 这是一个面向最终显示层的归一化入口。它会有意把十六进制、RGB、HSL 与 HSV
|
|
259
|
+
* 等不同语义层的字符串统一折叠为 sRGB;如果调用方需要保留输入本身的颜色语义,
|
|
260
|
+
* 应改用对应的专用解析函数。
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```
|
|
264
|
+
* // Expect: { red: 51, green: 102, blue: 153, alpha: 1 }
|
|
265
|
+
* const example1 = colorStringToSrgbColorValue("#336699")
|
|
266
|
+
*
|
|
267
|
+
* // Expect: { red: 51, green: 102, blue: 153, alpha: 1 }
|
|
268
|
+
* const example2 = colorStringToSrgbColorValue("hsl(210, 50%, 40%)")
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
export const colorStringToSrgbColorValue = (input: string): SrgbColorValue => {
|
|
272
|
+
const normalizedInput = input.trim()
|
|
273
|
+
if (normalizedInput.startsWith("#") || isHexColorString(normalizedInput) === true) {
|
|
274
|
+
return hexColorStringToSrgbColorValue(normalizedInput)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (normalizedInput.toLowerCase().startsWith("rgba(")) {
|
|
278
|
+
return rgbaColorStringToSrgbColorValue(normalizedInput)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (normalizedInput.toLowerCase().startsWith("rgb(")) {
|
|
282
|
+
return rgbColorStringToSrgbColorValue(normalizedInput)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (normalizedInput.toLowerCase().startsWith("hsla(")) {
|
|
286
|
+
return hslColorValueToSrgbColorValue(hslaColorStringToHslColorValue(normalizedInput))
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (normalizedInput.toLowerCase().startsWith("hsl(")) {
|
|
290
|
+
return hslColorValueToSrgbColorValue(hslColorStringToHslColorValue(normalizedInput))
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (normalizedInput.toLowerCase().startsWith("hsva(")) {
|
|
294
|
+
return hsvColorValueToSrgbColorValue(hsvaColorStringToHsvColorValue(normalizedInput))
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (normalizedInput.toLowerCase().startsWith("hsv(")) {
|
|
298
|
+
return hsvColorValueToSrgbColorValue(hsvColorStringToHsvColorValue(normalizedInput))
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
throw new TypeError("Invalid color string input")
|
|
302
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createHslColorValue,
|
|
3
|
+
createHsvColorValue,
|
|
4
|
+
createSrgbColorValue,
|
|
5
|
+
} from "./construct.ts"
|
|
6
|
+
import {
|
|
7
|
+
internalFormatAlpha,
|
|
8
|
+
internalFormatHexByte,
|
|
9
|
+
internalFormatPercentUnit,
|
|
10
|
+
} from "./internal.ts"
|
|
11
|
+
|
|
12
|
+
import type {
|
|
13
|
+
HslColorValue,
|
|
14
|
+
HsvColorValue,
|
|
15
|
+
SrgbColorValue,
|
|
16
|
+
} from "../types.ts"
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 将 sRGB 颜色值序列化为十六进制颜色字符串。
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```
|
|
23
|
+
* // Expect: #336699
|
|
24
|
+
* const example1 = srgbColorValueToHexColorString({ red: 51, green: 102, blue: 153, alpha: 0.5 })
|
|
25
|
+
*
|
|
26
|
+
* // Expect: #33669980
|
|
27
|
+
* const example2 = srgbColorValueToHexColorString({ red: 51, green: 102, blue: 153, alpha: 0.5 }, { includeAlpha: true })
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export const srgbColorValueToHexColorString = (color: SrgbColorValue, options: { includeAlpha?: boolean } = {}): string => {
|
|
31
|
+
const normalizedColor = createSrgbColorValue(color)
|
|
32
|
+
const hex = [normalizedColor.red, normalizedColor.green, normalizedColor.blue]
|
|
33
|
+
.map(value => internalFormatHexByte(value))
|
|
34
|
+
.join("")
|
|
35
|
+
|
|
36
|
+
if (options.includeAlpha === true) {
|
|
37
|
+
const alphaByte = Math.round(normalizedColor.alpha * 255)
|
|
38
|
+
return `#${hex}${internalFormatHexByte(alphaByte)}`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return `#${hex}`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 将 sRGB 颜色值序列化为 `rgb(...)` 字符串。
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```
|
|
49
|
+
* // Expect: rgb(51, 102, 153)
|
|
50
|
+
* const example1 = srgbColorValueToRgbColorString({ red: 51, green: 102, blue: 153, alpha: 0.5 })
|
|
51
|
+
*
|
|
52
|
+
* // Expect: rgb(0, 0, 0)
|
|
53
|
+
* const example2 = srgbColorValueToRgbColorString({ red: 0, green: 0, blue: 0, alpha: 1 })
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export const srgbColorValueToRgbColorString = (color: SrgbColorValue): string => {
|
|
57
|
+
const normalizedColor = createSrgbColorValue(color)
|
|
58
|
+
return `rgb(${normalizedColor.red}, ${normalizedColor.green}, ${normalizedColor.blue})`
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 将 sRGB 颜色值序列化为 `rgba(...)` 字符串。
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```
|
|
66
|
+
* // Expect: rgba(51, 102, 153, 0.5)
|
|
67
|
+
* const example1 = srgbColorValueToRgbaColorString({ red: 51, green: 102, blue: 153, alpha: 0.5 })
|
|
68
|
+
*
|
|
69
|
+
* // Expect: rgba(255, 255, 255, 1)
|
|
70
|
+
* const example2 = srgbColorValueToRgbaColorString({ red: 255, green: 255, blue: 255, alpha: 1 })
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export const srgbColorValueToRgbaColorString = (color: SrgbColorValue): string => {
|
|
74
|
+
const normalizedColor = createSrgbColorValue(color)
|
|
75
|
+
return `rgba(${normalizedColor.red}, ${normalizedColor.green}, ${normalizedColor.blue}, ${internalFormatAlpha(normalizedColor.alpha)})`
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 将 HSL 颜色值序列化为 `hsl(...)` 字符串。
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```
|
|
83
|
+
* // Expect: hsl(210, 50%, 40%)
|
|
84
|
+
* const example1 = hslColorValueToHslColorString({ hue: 210, saturation: 0.5, lightness: 0.4, alpha: 0.5 })
|
|
85
|
+
*
|
|
86
|
+
* // Expect: hsl(0, 0%, 100%)
|
|
87
|
+
* const example2 = hslColorValueToHslColorString({ hue: 0, saturation: 0, lightness: 1, alpha: 1 })
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export const hslColorValueToHslColorString = (color: HslColorValue): string => {
|
|
91
|
+
const normalizedColor = createHslColorValue(color)
|
|
92
|
+
return `hsl(${normalizedColor.hue}, ${internalFormatPercentUnit(normalizedColor.saturation)}%, ${internalFormatPercentUnit(normalizedColor.lightness)}%)`
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* 将 HSL 颜色值序列化为 `hsla(...)` 字符串。
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```
|
|
100
|
+
* // Expect: hsla(210, 50%, 40%, 0.5)
|
|
101
|
+
* const example1 = hslColorValueToHslaColorString({ hue: 210, saturation: 0.5, lightness: 0.4, alpha: 0.5 })
|
|
102
|
+
*
|
|
103
|
+
* // Expect: hsla(0, 0%, 100%, 1)
|
|
104
|
+
* const example2 = hslColorValueToHslaColorString({ hue: 0, saturation: 0, lightness: 1, alpha: 1 })
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export const hslColorValueToHslaColorString = (color: HslColorValue): string => {
|
|
108
|
+
const normalizedColor = createHslColorValue(color)
|
|
109
|
+
return `hsla(${normalizedColor.hue}, ${internalFormatPercentUnit(normalizedColor.saturation)}%, ${internalFormatPercentUnit(normalizedColor.lightness)}%, ${internalFormatAlpha(normalizedColor.alpha)})`
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 将 HSV 颜色值序列化为 `hsv(...)` 字符串。
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```
|
|
117
|
+
* // Expect: hsv(210, 66.67%, 60%)
|
|
118
|
+
* const example1 = hsvColorValueToHsvColorString({ hue: 210, saturation: 0.6667, value: 0.6, alpha: 0.5 })
|
|
119
|
+
*
|
|
120
|
+
* // Expect: hsv(0, 0%, 100%)
|
|
121
|
+
* const example2 = hsvColorValueToHsvColorString({ hue: 0, saturation: 0, value: 1, alpha: 1 })
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export const hsvColorValueToHsvColorString = (color: HsvColorValue): string => {
|
|
125
|
+
const normalizedColor = createHsvColorValue(color)
|
|
126
|
+
return `hsv(${normalizedColor.hue}, ${internalFormatPercentUnit(normalizedColor.saturation)}%, ${internalFormatPercentUnit(normalizedColor.value)}%)`
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* 将 HSV 颜色值序列化为 `hsva(...)` 字符串。
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```
|
|
134
|
+
* // Expect: hsva(210, 66.67%, 60%, 0.5)
|
|
135
|
+
* const example1 = hsvColorValueToHsvaColorString({ hue: 210, saturation: 0.6667, value: 0.6, alpha: 0.5 })
|
|
136
|
+
*
|
|
137
|
+
* // Expect: hsva(0, 0%, 100%, 1)
|
|
138
|
+
* const example2 = hsvColorValueToHsvaColorString({ hue: 0, saturation: 0, value: 1, alpha: 1 })
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export const hsvColorValueToHsvaColorString = (color: HsvColorValue): string => {
|
|
142
|
+
const normalizedColor = createHsvColorValue(color)
|
|
143
|
+
return `hsva(${normalizedColor.hue}, ${internalFormatPercentUnit(normalizedColor.saturation)}%, ${internalFormatPercentUnit(normalizedColor.value)}%, ${internalFormatAlpha(normalizedColor.alpha)})`
|
|
144
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 表示 XYZ 颜色值结构,使用 `x`、`y`、`z` 三个通道和 `alpha` 透明度通道。
|
|
3
|
+
*/
|
|
4
|
+
export type XyzColorValue = Readonly<{
|
|
5
|
+
x: number
|
|
6
|
+
y: number
|
|
7
|
+
z: number
|
|
8
|
+
alpha: number
|
|
9
|
+
}>
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 表示基于 XYZ 颜色值计算得到的 `xy` 色度坐标结构。
|
|
13
|
+
*/
|
|
14
|
+
export type XyChromaticityValue = Readonly<{
|
|
15
|
+
x: number
|
|
16
|
+
y: number
|
|
17
|
+
}>
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 表示 Linear RGB 颜色值结构,使用线性 `red`、`green`、`blue` 三个通道和 `alpha` 透明度通道。
|
|
21
|
+
*/
|
|
22
|
+
export type LinearRgbColorValue = Readonly<{
|
|
23
|
+
red: number
|
|
24
|
+
green: number
|
|
25
|
+
blue: number
|
|
26
|
+
alpha: number
|
|
27
|
+
}>
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 表示 sRGB 颜色值结构,使用 `red`、`green`、`blue` 三个 8 位通道和 `alpha` 透明度通道。
|
|
31
|
+
*/
|
|
32
|
+
export type SrgbColorValue = Readonly<{
|
|
33
|
+
red: number
|
|
34
|
+
green: number
|
|
35
|
+
blue: number
|
|
36
|
+
alpha: number
|
|
37
|
+
}>
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 表示 HSL 颜色值结构,使用 `hue`、`saturation`、`lightness` 和 `alpha` 四个通道。
|
|
41
|
+
*/
|
|
42
|
+
export type HslColorValue = Readonly<{
|
|
43
|
+
hue: number
|
|
44
|
+
saturation: number
|
|
45
|
+
lightness: number
|
|
46
|
+
alpha: number
|
|
47
|
+
}>
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 表示 HSV 颜色值结构,使用 `hue`、`saturation`、`value` 和 `alpha` 四个通道。
|
|
51
|
+
*/
|
|
52
|
+
export type HsvColorValue = Readonly<{
|
|
53
|
+
hue: number
|
|
54
|
+
saturation: number
|
|
55
|
+
value: number
|
|
56
|
+
alpha: number
|
|
57
|
+
}>
|