ph-utils 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -1,11 +1,7 @@
1
- ## ph-utils
2
-
3
- 整理了 js 前后端开发(web + nodejs)时常用的一些工具;[详细文档](https://gitee.com/towardly/ph/wikis/Home?sort_id=4035190)
4
-
5
- ### 后端(node server)
6
-
7
- 包含了一些 node 后端开发(web server) 时常用的工具类,包括 `index` 基础工具类(这个类里面的函数同样也适用于前端)、`date` 跟日期相关的工具类、`file` 文件操作相关工具类、`server` 一些只适用于后端的工具(使用了后端的 API 列表)、`validator` 数据验证
8
-
9
- ### 前端(web)
10
-
11
- 包含了一些前端网站开发时常用的工具类,包括 `index` 基础工具类(这个类里面的函数同样也适用于前端)、`date` 跟日期相关的工具类、`dom` 浏览器节点操作相关、`web` 一些只适用于前端相关的工具、`validator` 数据验证
1
+ ## ph-utils
2
+
3
+ 整理了 js 前后端开发(web + nodejs)时常用的一些工具;[详细文档](https://gitee.com/towardly/ph/wikis/Home?sort_id=4035190)
4
+
5
+ ### 包含如下工具文件
6
+
7
+ `index` 基础工具类、`date` 跟日期相关的工具类、`file` 文件操作相关工具类[**服务端**]、`server` 服务端工具类、`validator` 数据验证、`dom` 浏览器节点操作相关[**前端**]、`web` 一些只适用于前端相关的工具、`color` 颜色相关工具
package/lib/color.d.ts ADDED
@@ -0,0 +1,47 @@
1
+ type RGBColorObject = {
2
+ r: number;
3
+ g: number;
4
+ b: number;
5
+ a?: number;
6
+ };
7
+ type HSVColorObject = {
8
+ h: number;
9
+ s: number;
10
+ v: number;
11
+ };
12
+ /**
13
+ * 将输入的颜色值转换为RGB对象格式。
14
+ *
15
+ * @param color 可以是字符串, 也可以是一个 HSV 对象[一个包含 h、s、v 属性的对象]
16
+ * @returns 返回一个包含r、g、b和a(透明度)属性的RGB对象。
17
+ * @throws 如果输入的字符串不是有效的颜色表示,则抛出错误。
18
+ */
19
+ export declare function toRgb(color: any): RGBColorObject;
20
+ /**
21
+ * 将颜色转换为HSV颜色模型。
22
+ *
23
+ * @param color - 字符串或者RGB对象
24
+ * @returns 返回一个包含h、s、v属性的对象,代表HSV颜色值,其中h是色相(取值范围0到360),s是饱和度(取值范围0到1),v是明度(取值范围0到1)。
25
+ */
26
+ export declare function toHsv(color: any): HSVColorObject;
27
+ /**
28
+ * 将RGB颜色对象转换为十六进制颜色字符串。
29
+ * @param rgb - 包含红色(r), 绿色(g), 蓝色(b)成分的对象。
30
+ * @returns 返回一个表示RGB颜色的十六进制字符串,例如"#FF0000"。
31
+ */
32
+ export declare function rgbToHex(rgb: RGBColorObject): string;
33
+ /**
34
+ * 将颜色转换为 16 进制字符串
35
+ * @param color - 颜色, 可以 rgb(0,0,0),rgba(0,0,0,0)字符串, 也可以是 rgb、hsv对象
36
+ * @returns 返回颜色的十六进制字符串,例如"#FF0000"
37
+ */
38
+ export declare function toHex(color: any): string;
39
+ /**
40
+ * 调整给定颜色深[darken]浅[lighten]
41
+ * @param color - 输入的颜色,可以是任意颜色表示方式
42
+ * @param level - 调整深浅级别, 可以是小数
43
+ * @param light - 控制调整的方向。如果为true,[lighten] 变浅,如果为false,[darken] 变深。
44
+ * @returns 返回调整后颜色的十六进制字符串表示。
45
+ */
46
+ export declare function adjust(color: any, level?: number, light?: boolean): string;
47
+ export {};
package/lib/color.js ADDED
@@ -0,0 +1,292 @@
1
+ const hueStep = 2; // 色相阶梯
2
+ const saturationStep = 0.16; // 饱和度阶梯,浅色部分
3
+ const saturationStep2 = 0.05; // 饱和度阶梯,深色部分
4
+ const brightnessStep1 = 0.05; // 亮度阶梯,浅色部分
5
+ const brightnessStep2 = 0.15; // 亮度阶梯,深色部分
6
+ /* 解析: rgb(0,0,0), rgba(0,0,0,0.1) 格式的正则 */
7
+ const rgbRegex = /rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d*\.?\d+))?\s*\)/;
8
+ /* 匹配 16 进制颜色字符串的正则: #fff, #ffffff */
9
+ const hexRegex = /^#(?:([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})|([0-9A-Fa-f]{1})([0-9A-Fa-f]{1})([0-9A-Fa-f]{1}))$/;
10
+ function isRgb(color) {
11
+ return color.r != null && color.g != null && color.b != null;
12
+ }
13
+ function isHsv(color) {
14
+ return color.h != null && color.s != null && color.v != null;
15
+ }
16
+ function parseRgbString(color) {
17
+ let colorValue = color.match(rgbRegex);
18
+ if (colorValue != null) {
19
+ const r = parseInt(colorValue[1].trim());
20
+ const g = parseInt(colorValue[2].trim());
21
+ const b = parseInt(colorValue[3].trim());
22
+ // 检查RGB值是否为NaN
23
+ if (isNaN(r) || isNaN(g) || isNaN(b)) {
24
+ throw new Error("Invalid RGB color.");
25
+ }
26
+ let a = 1;
27
+ // 如果是RGBA,解析透明度值
28
+ if (colorValue[4] != null) {
29
+ a = parseFloat(colorValue[4].trim());
30
+ if (isNaN(a)) {
31
+ a = 1;
32
+ }
33
+ }
34
+ return {
35
+ r,
36
+ g,
37
+ b,
38
+ a,
39
+ };
40
+ }
41
+ }
42
+ function parseHexString(color) {
43
+ const colorMatch = color.match(hexRegex);
44
+ if (colorMatch != null) {
45
+ // 判断是否是缩写形式的颜色(3个字符)
46
+ const isShortForm = colorMatch[4] !== undefined;
47
+ const r = parseInt(isShortForm ? colorMatch[4] + colorMatch[4] : colorMatch[1], 16);
48
+ const g = parseInt(isShortForm ? colorMatch[5] + colorMatch[5] : colorMatch[2], 16);
49
+ const b = parseInt(isShortForm ? colorMatch[6] + colorMatch[6] : colorMatch[3], 16);
50
+ return {
51
+ r,
52
+ g,
53
+ b,
54
+ };
55
+ }
56
+ }
57
+ /**
58
+ * 将输入的颜色值转换为RGB对象格式。
59
+ *
60
+ * @param color 可以是字符串, 也可以是一个 HSV 对象[一个包含 h、s、v 属性的对象]
61
+ * @returns 返回一个包含r、g、b和a(透明度)属性的RGB对象。
62
+ * @throws 如果输入的字符串不是有效的颜色表示,则抛出错误。
63
+ */
64
+ export function toRgb(color) {
65
+ if (typeof color === "string") {
66
+ let rgb = parseHexString(color);
67
+ if (rgb == null) {
68
+ rgb = parseRgbString(color);
69
+ }
70
+ if (rgb != null) {
71
+ return rgb;
72
+ }
73
+ throw new Error("Invalid color string");
74
+ }
75
+ else {
76
+ // 处理RGB对象输入
77
+ if (isRgb(color)) {
78
+ return color;
79
+ }
80
+ else if (isHsv(color)) {
81
+ return hsvToRgb(color);
82
+ }
83
+ throw new Error("Invalid color");
84
+ }
85
+ }
86
+ /**
87
+ * 将颜色转换为HSV颜色模型。
88
+ *
89
+ * @param color - 字符串或者RGB对象
90
+ * @returns 返回一个包含h、s、v属性的对象,代表HSV颜色值,其中h是色相(取值范围0到360),s是饱和度(取值范围0到1),v是明度(取值范围0到1)。
91
+ */
92
+ export function toHsv(color) {
93
+ if (isHsv(color))
94
+ return color;
95
+ const rgbColor = toRgb(color);
96
+ // 将RGB值标准化到0到1的范围
97
+ const r = rgbColor.r / 255;
98
+ const g = rgbColor.g / 255;
99
+ const b = rgbColor.b / 255;
100
+ // 获取最大和最小值,计算色彩的明度(V)
101
+ let max = Math.max(r, g, b);
102
+ let min = Math.min(r, g, b);
103
+ let delta = max - min;
104
+ let v = max;
105
+ // 计算饱和度(S)
106
+ let s = max === 0 ? 0 : delta / max;
107
+ // 计算色相(H)
108
+ let h = 0;
109
+ if (max === min) {
110
+ h = 0; // achromatic (no hue)
111
+ }
112
+ else {
113
+ // 根据最大值和最小值的不同,计算色相
114
+ switch (max) {
115
+ case r:
116
+ h = ((g - b) / delta + (g < b ? 6 : 0)) / 6;
117
+ break;
118
+ case g:
119
+ h = ((b - r) / delta + 2) / 6;
120
+ break;
121
+ case b:
122
+ h = ((r - g) / delta + 4) / 6;
123
+ break;
124
+ }
125
+ }
126
+ // 将色相值乘以360,转换为度数
127
+ h = h * 360;
128
+ return { h, s, v };
129
+ }
130
+ /**
131
+ * 将HSV颜色模型转换为RGB颜色模型。
132
+ * @param hsv 包含色相(h)、饱和度(s)和明度(v)的对象。s 和 v 可以是 0~1之间的小数, 也可以是 0~100 直接的整数, 推荐为小数,结果更精准
133
+ * @returns 返回一个包含红色(r)、绿色(g)和蓝色(b)值的对象,范围为0-255。
134
+ */
135
+ function hsvToRgb(hsv) {
136
+ // 将百分比形式的饱和度和明度转换为0-1的数值
137
+ let s = hsv.s;
138
+ let v = hsv.v;
139
+ if (s > 1) {
140
+ s /= 100;
141
+ }
142
+ if (v > 1) {
143
+ v /= 100;
144
+ }
145
+ const h = hsv.h;
146
+ // 根据色相值计算色相角,并计算出六个区域中的位置
147
+ var hi = Math.floor(h / 60) % 6;
148
+ var f = h / 60 - Math.floor(h / 60);
149
+ var p = v * (1 - s);
150
+ var q = v * (1 - f * s);
151
+ var t = v * (1 - (1 - f) * s);
152
+ // 根据色相角确定RGB值的具体计算
153
+ let r = 0, g = 0, b = 0;
154
+ switch (hi) {
155
+ case 0:
156
+ r = v;
157
+ g = t;
158
+ b = p;
159
+ break;
160
+ case 1:
161
+ r = q;
162
+ g = v;
163
+ b = p;
164
+ break;
165
+ case 2:
166
+ r = p;
167
+ g = v;
168
+ b = t;
169
+ break;
170
+ case 3:
171
+ r = p;
172
+ g = q;
173
+ b = v;
174
+ break;
175
+ case 4:
176
+ r = t;
177
+ g = p;
178
+ b = v;
179
+ break;
180
+ case 5:
181
+ r = v;
182
+ g = p;
183
+ b = q;
184
+ break;
185
+ }
186
+ // 将计算得到的RGB值从0-1范围转换为0-255范围
187
+ r = Math.round(r * 255);
188
+ g = Math.round(g * 255);
189
+ b = Math.round(b * 255);
190
+ return { r, g, b };
191
+ }
192
+ function getHue(hsv, i, light) {
193
+ let hue;
194
+ // 根据色相不同,色相转向不同
195
+ if (Math.round(hsv.h) >= 60 && Math.round(hsv.h) <= 240) {
196
+ hue = light
197
+ ? Math.round(hsv.h) - hueStep * i
198
+ : Math.round(hsv.h) + hueStep * i;
199
+ }
200
+ else {
201
+ hue = light
202
+ ? Math.round(hsv.h) + hueStep * i
203
+ : Math.round(hsv.h) - hueStep * i;
204
+ }
205
+ if (hue < 0) {
206
+ hue += 360;
207
+ }
208
+ else if (hue >= 360) {
209
+ hue -= 360;
210
+ }
211
+ return hue;
212
+ }
213
+ function getSaturation(hsv, i, light) {
214
+ // grey color don't change saturation
215
+ if (hsv.h === 0 && hsv.s === 0) {
216
+ return hsv.s;
217
+ }
218
+ let saturation;
219
+ if (light) {
220
+ saturation = hsv.s - saturationStep * i;
221
+ }
222
+ else {
223
+ saturation = hsv.s + saturationStep2 * i;
224
+ }
225
+ // 边界值修正
226
+ if (saturation > 1) {
227
+ saturation = 1;
228
+ }
229
+ // 第一格的 s 限制在 0.06-0.1 之间
230
+ if (light && saturation > 0.1) {
231
+ saturation = 0.1;
232
+ }
233
+ if (saturation < 0.06) {
234
+ saturation = 0.06;
235
+ }
236
+ return Number(saturation.toFixed(2));
237
+ }
238
+ function getValue(hsv, i, light) {
239
+ let value;
240
+ if (light) {
241
+ value = hsv.v + brightnessStep1 * i;
242
+ }
243
+ else {
244
+ value = hsv.v - brightnessStep2 * i;
245
+ }
246
+ if (value > 1) {
247
+ value = 1;
248
+ }
249
+ return Number(value.toFixed(2));
250
+ }
251
+ /**
252
+ * 将RGB颜色对象转换为十六进制颜色字符串。
253
+ * @param rgb - 包含红色(r), 绿色(g), 蓝色(b)成分的对象。
254
+ * @returns 返回一个表示RGB颜色的十六进制字符串,例如"#FF0000"。
255
+ */
256
+ export function rgbToHex(rgb) {
257
+ // 将一个数字转换为两位数的十六进制字符串
258
+ const toHex = (n) => n.toString(16).padStart(2, "0");
259
+ // 将RGB颜色值转换为十六进制字符串并大写化
260
+ return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`.toUpperCase();
261
+ }
262
+ /**
263
+ * 将颜色转换为 16 进制字符串
264
+ * @param color - 颜色, 可以 rgb(0,0,0),rgba(0,0,0,0)字符串, 也可以是 rgb、hsv对象
265
+ * @returns 返回颜色的十六进制字符串,例如"#FF0000"
266
+ */
267
+ export function toHex(color) {
268
+ if (typeof color === "string") {
269
+ if (hexRegex.test(color)) {
270
+ return color;
271
+ }
272
+ return rgbToHex(toRgb(color));
273
+ }
274
+ return rgbToHex(toRgb(color));
275
+ }
276
+ /**
277
+ * 调整给定颜色深[darken]浅[lighten]
278
+ * @param color - 输入的颜色,可以是任意颜色表示方式
279
+ * @param level - 调整深浅级别, 可以是小数
280
+ * @param light - 控制调整的方向。如果为true,[lighten] 变浅,如果为false,[darken] 变深。
281
+ * @returns 返回调整后颜色的十六进制字符串表示。
282
+ */
283
+ export function adjust(color, level = 1, light = true) {
284
+ // 将输入的颜色转换为HSV格式
285
+ const hsv = toHsv(color);
286
+ // 根据level和light参数调整颜色的H、S、V值,并转换回十六进制颜色表示
287
+ return toHex({
288
+ h: getHue(hsv, level, light),
289
+ s: getSaturation(hsv, level, light),
290
+ v: getValue(hsv, level, light),
291
+ });
292
+ }
package/lib/index.d.ts CHANGED
@@ -86,4 +86,15 @@ export declare function formatMoney(number: number): string;
86
86
  * @param connector 连接符, 默认为: _
87
87
  */
88
88
  export declare function snakeCaseStyle(name: string, connector?: string): string;
89
+ /**
90
+ * 对数字进行四舍五入处理
91
+ * @param num 需要进行四舍五入的数字
92
+ * @param precision 精度,默认为2,即保留小数点后两位
93
+ * @param roundType 舍入类型,默认为0,提供三种取值:
94
+ * 0: 标准四舍五入
95
+ * 1: 向上取整
96
+ * 2: 向下取整
97
+ * @returns 返回经过指定方式舍入后的数字
98
+ */
99
+ export declare function round(num: number, precision?: number, roundType?: 0 | 1 | 2): number;
89
100
  export {};
package/lib/index.js CHANGED
@@ -150,3 +150,31 @@ export function formatMoney(number) {
150
150
  export function snakeCaseStyle(name, connector = "-") {
151
151
  return name.replace(/([A-Z])/g, (match, p1, offset) => (offset > 0 ? connector : "") + match.toLowerCase());
152
152
  }
153
+ /**
154
+ * 对数字进行四舍五入处理
155
+ * @param num 需要进行四舍五入的数字
156
+ * @param precision 精度,默认为2,即保留小数点后两位
157
+ * @param roundType 舍入类型,默认为0,提供三种取值:
158
+ * 0: 标准四舍五入
159
+ * 1: 向上取整
160
+ * 2: 向下取整
161
+ * @returns 返回经过指定方式舍入后的数字
162
+ */
163
+ export function round(num, precision = 2, roundType = 0) {
164
+ // 计算精度因子,用于后续四舍五入计算
165
+ const factor = Math.pow(10, precision);
166
+ switch (roundType) {
167
+ case 0:
168
+ // 标准四舍五入
169
+ return Math.round(num * factor) / factor;
170
+ case 1:
171
+ // 向上取整
172
+ return Math.ceil(num * factor) / factor;
173
+ case 2:
174
+ // 向下取整
175
+ return Math.floor(num * factor) / factor;
176
+ default:
177
+ // 如果传入的roundType不是预期的值,则直接返回原始数字
178
+ return num;
179
+ }
180
+ }
package/lib/storage.js CHANGED
@@ -12,7 +12,7 @@ export function set(key, value, option) {
12
12
  const opts = {
13
13
  expire: -1,
14
14
  storage: "session",
15
- ...(option || {}),
15
+ ...option,
16
16
  };
17
17
  const saveData = JSON.stringify({
18
18
  value,
package/package.json CHANGED
@@ -46,9 +46,13 @@
46
46
  "types": "./lib/storage.d.ts",
47
47
  "import": "./lib/storage.js"
48
48
  },
49
+ "./color": {
50
+ "types": "./lib/color.d.ts",
51
+ "import": "./lib/color.js"
52
+ },
49
53
  "./*": "./lib/*"
50
54
  },
51
- "version": "0.4.3",
55
+ "version": "0.4.4",
52
56
  "type": "module",
53
57
  "repository": {
54
58
  "type": "git",
@@ -56,14 +60,14 @@
56
60
  "directory": "packages/utils"
57
61
  },
58
62
  "license": "MIT",
59
- "author": "DvShu <1456207945@qq.com>",
63
+ "author": "Tenny <tenny.shu@foxmail.com>",
60
64
  "bugs": {
61
65
  "url": "https://gitee.com/towardly/ph/issues"
62
66
  },
63
67
  "homepage": "https://gitee.com/towardly/ph/tree/master/packages/utils",
64
68
  "devDependencies": {
65
- "@types/node": "^20.9.0",
66
- "typescript": "^5.2.2"
69
+ "@types/node": "^20.12.12",
70
+ "typescript": "^5.4.5"
67
71
  },
68
72
  "files": [
69
73
  "lib"
@@ -76,6 +80,9 @@
76
80
  "dom",
77
81
  "file"
78
82
  ],
83
+ "dependencies": {
84
+ "@ctrl/tinycolor": "^4.1.0"
85
+ },
79
86
  "scripts": {
80
87
  "build": "node scripts/build.js"
81
88
  }