@cowave-cli/utils 2.5.3
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/README.md +115 -0
- package/dist/error.d.ts +1 -0
- package/dist/js/fullscreen.d.ts +24 -0
- package/dist/js/http.d.ts +26 -0
- package/dist/js/logic.d.ts +1 -0
- package/dist/js/navigator.d.ts +9 -0
- package/dist/js/number.d.ts +15 -0
- package/dist/js/object.d.ts +52 -0
- package/dist/js/string.d.ts +44 -0
- package/dist/js/style.d.ts +6 -0
- package/dist/js/time.d.ts +77 -0
- package/dist/js/tiny-color.d.ts +288 -0
- package/dist/js.cjs +1652 -0
- package/dist/js.d.ts +10 -0
- package/dist/js.js +1627 -0
- package/dist/node/file.d.ts +40 -0
- package/dist/node/path.d.ts +26 -0
- package/dist/node.cjs +1883 -0
- package/dist/node.d.ts +3 -0
- package/dist/node.js +1849 -0
- package/dist/vue/api.d.ts +28 -0
- package/dist/vue/file.d.ts +16 -0
- package/dist/vue/store.d.ts +2 -0
- package/dist/vue/subscribe.d.ts +4 -0
- package/dist/vue.cjs +1846 -0
- package/dist/vue.d.ts +5 -0
- package/dist/vue.js +1816 -0
- package/package.json +77 -0
- package/type.d.ts +17 -0
package/dist/vue.js
ADDED
|
@@ -0,0 +1,1816 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { cloneDeep, throttle, debounce } from 'lodash';
|
|
3
|
+
import { isRef, isReactive, unref, toRaw, onMounted, onUnmounted, ref } from 'vue';
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* @Description: 字符串处理
|
|
7
|
+
* @Author: Zye
|
|
8
|
+
* @Date: 2024-03-11
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated 这个函数已弃用,请使用 toHump() 代替
|
|
12
|
+
*/
|
|
13
|
+
const pathToHump = (path, isGreatHump = true) => {
|
|
14
|
+
if (isGreatHump) {
|
|
15
|
+
path = path.replace(/^([a-z])/g, (_, p1) => p1.toUpperCase());
|
|
16
|
+
}
|
|
17
|
+
path = path.replace(/-([a-z])/g, (_, p1) => p1.toUpperCase());
|
|
18
|
+
return path;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* 将连接符字符串转换为驼峰字符串
|
|
22
|
+
*
|
|
23
|
+
* @param strings 字符串(列表)
|
|
24
|
+
* @param hyphenType 连接符
|
|
25
|
+
* @param isGreatHump 是否为大驼峰
|
|
26
|
+
* @returns humpString
|
|
27
|
+
*/
|
|
28
|
+
const toHump = (strings, hyphenType = '-', isGreatHump = false) => {
|
|
29
|
+
hyphenType = hyphenType || '-';
|
|
30
|
+
const results = (typeof strings === 'string' ? [strings] : strings).map(string => {
|
|
31
|
+
if (isGreatHump) {
|
|
32
|
+
string = string.replace(/^([a-z])/g, (_, p1) => p1.toUpperCase());
|
|
33
|
+
}
|
|
34
|
+
string = string.replace(new RegExp(hyphenType + '([a-z])', 'g'), (_, p1) => p1.toUpperCase());
|
|
35
|
+
return string;
|
|
36
|
+
});
|
|
37
|
+
return typeof strings === 'string' ? results[0] : results;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* 将驼峰字符串转换为连接符字符串
|
|
41
|
+
*
|
|
42
|
+
* @param strings 字符串(列表)
|
|
43
|
+
* @param hyphenType 连接符
|
|
44
|
+
* @returns hyphenString
|
|
45
|
+
*/
|
|
46
|
+
const toHyphen = (strings, hyphenType = '-') => {
|
|
47
|
+
const results = (typeof strings === 'string' ? [strings] : strings).map(string => {
|
|
48
|
+
string = string.replace(/^([A-Z])/g, (_, p1) => p1.toLowerCase());
|
|
49
|
+
string = string.replace(/([A-Z])/g, (_, p1) => hyphenType + p1.toLowerCase());
|
|
50
|
+
});
|
|
51
|
+
return typeof strings === 'string' ? results[0] : results;
|
|
52
|
+
};
|
|
53
|
+
// 字符串拼接
|
|
54
|
+
/**
|
|
55
|
+
* 将object转换成query参数
|
|
56
|
+
*
|
|
57
|
+
* @param keyValue 对象
|
|
58
|
+
* @returns query参数
|
|
59
|
+
*/
|
|
60
|
+
const query = (keyValue) => {
|
|
61
|
+
return keyValue
|
|
62
|
+
? '?' +
|
|
63
|
+
Object.keys(keyValue)
|
|
64
|
+
.filter((key) => keyValue[key] !== undefined && keyValue[key] !== null)
|
|
65
|
+
.map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(keyValue[key]))
|
|
66
|
+
.join('&')
|
|
67
|
+
: '';
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* 将url 传参转成data格式
|
|
72
|
+
*
|
|
73
|
+
* @param url (?********)
|
|
74
|
+
* @returns
|
|
75
|
+
*/
|
|
76
|
+
const urlToData = (url) => {
|
|
77
|
+
const res = [];
|
|
78
|
+
const index = url.indexOf('?');
|
|
79
|
+
if (index === -1)
|
|
80
|
+
return [{ key: '', value: '' }];
|
|
81
|
+
url
|
|
82
|
+
.slice(index + 1)
|
|
83
|
+
.split('&')
|
|
84
|
+
.forEach((v) => {
|
|
85
|
+
res.push({
|
|
86
|
+
key: decodeURI(v.split('=')[0]),
|
|
87
|
+
value: decodeURI(v.split('=')[1]),
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
return [
|
|
91
|
+
...res,
|
|
92
|
+
{
|
|
93
|
+
key: '',
|
|
94
|
+
value: '',
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
*
|
|
100
|
+
* 判断url格式
|
|
101
|
+
*
|
|
102
|
+
* @param url
|
|
103
|
+
* @returns
|
|
104
|
+
*/
|
|
105
|
+
const isUrl = (path) => {
|
|
106
|
+
const reg = /^(https?:\/\/)([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)\/?(\?[^\s#]*)?$/;
|
|
107
|
+
return reg.test(path);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/*
|
|
111
|
+
* @Description: 时间处理
|
|
112
|
+
* @Author: Zye
|
|
113
|
+
* @Date: 2024-03-11
|
|
114
|
+
*
|
|
115
|
+
* setTime(time) time -> 服务器时间
|
|
116
|
+
* getTime() 返回服务器时间戳
|
|
117
|
+
*
|
|
118
|
+
*/
|
|
119
|
+
// 服务器时间戳 减去 客户端时间戳
|
|
120
|
+
let _time_diff = 0;
|
|
121
|
+
// 同步时间
|
|
122
|
+
/**
|
|
123
|
+
* @param callback 获取服务器时间的回调函数,需要返回服务器时间
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
*
|
|
127
|
+
* setTime(async () => {
|
|
128
|
+
* return await getServerTime()
|
|
129
|
+
* })
|
|
130
|
+
*
|
|
131
|
+
*/
|
|
132
|
+
const setTime = async (callback) => {
|
|
133
|
+
let _time_before, _time_after, _time_server;
|
|
134
|
+
_time_before = new Date().getTime();
|
|
135
|
+
_time_server = new Date(await callback()).getTime();
|
|
136
|
+
_time_after = new Date().getTime();
|
|
137
|
+
_time_diff = _time_diff
|
|
138
|
+
? (_time_diff + _time_server - _time_before / 2 - _time_after / 2) / 2
|
|
139
|
+
: _time_server - _time_before / 2 - _time_after / 2;
|
|
140
|
+
};
|
|
141
|
+
// 获取本地时间戳
|
|
142
|
+
const _local_time = () => new Date().getTime();
|
|
143
|
+
/**
|
|
144
|
+
* 获取服务器时间戳
|
|
145
|
+
*
|
|
146
|
+
* @returns 服务器时间戳
|
|
147
|
+
*/
|
|
148
|
+
const getTime = () => _local_time() + _time_diff;
|
|
149
|
+
/** 时间格式化 (参考dayjs)
|
|
150
|
+
*
|
|
151
|
+
* @param date 时间
|
|
152
|
+
* @param formatStr 格式如下
|
|
153
|
+
* @returns 格式化后的时间
|
|
154
|
+
*
|
|
155
|
+
* @formatStr
|
|
156
|
+
*
|
|
157
|
+
* |格式 |输出| 描述|
|
|
158
|
+
* |----|----|----|
|
|
159
|
+
* |YY| 18 |两位数年份|
|
|
160
|
+
* |YYYY| 2018 |四位数年份|
|
|
161
|
+
* |M| 1-12 |月份,从 1 开始|
|
|
162
|
+
* |MM |01-12 |月份,2 位数字|
|
|
163
|
+
* |D |1-31 |该月的哪一天|
|
|
164
|
+
* |DD| 01-31| 月份中的日期,2 位数字|
|
|
165
|
+
* |h| 0-23| 小时|
|
|
166
|
+
* |hh |00-23 |小时,2 位数字|
|
|
167
|
+
* |m| 0-59| 分钟|
|
|
168
|
+
* |mm |00-59 |分钟,2 位数字|
|
|
169
|
+
* |s |0-59| 秒钟|
|
|
170
|
+
* |ss |00-59 |秒钟,2 位数字|
|
|
171
|
+
*/
|
|
172
|
+
const getDate = (date, formatStr) => {
|
|
173
|
+
if (!date)
|
|
174
|
+
date = getTime();
|
|
175
|
+
if (typeof date == 'string' || typeof date == 'number') {
|
|
176
|
+
date = new Date(date);
|
|
177
|
+
}
|
|
178
|
+
if (!formatStr)
|
|
179
|
+
return new Date(date);
|
|
180
|
+
let ret;
|
|
181
|
+
let d = {
|
|
182
|
+
year: date.getFullYear().toString(),
|
|
183
|
+
month: (date.getMonth() + 1).toString(),
|
|
184
|
+
day: date.getDate().toString(),
|
|
185
|
+
hour: date.getHours().toString(),
|
|
186
|
+
minutes: date.getMinutes().toString(),
|
|
187
|
+
seconds: date.getSeconds().toString(),
|
|
188
|
+
week: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'][date.getDay()],
|
|
189
|
+
};
|
|
190
|
+
let keys = {
|
|
191
|
+
'YYYY': d.year,
|
|
192
|
+
'YY': d.year.slice(2),
|
|
193
|
+
'M+': d.month,
|
|
194
|
+
'D+': d.day,
|
|
195
|
+
'[Hh]+': d.hour,
|
|
196
|
+
'm+': d.minutes,
|
|
197
|
+
's+': d.seconds,
|
|
198
|
+
'[Ww]+': d.week,
|
|
199
|
+
};
|
|
200
|
+
for (let key in keys) {
|
|
201
|
+
ret = new RegExp('(' + key + ')').exec(formatStr);
|
|
202
|
+
if (ret) {
|
|
203
|
+
formatStr = formatStr.replace(ret[1], keys[key].padStart(ret[1].length, '0'));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return formatStr;
|
|
207
|
+
};
|
|
208
|
+
/** 获取特殊时间节点
|
|
209
|
+
*
|
|
210
|
+
* @param {'weekstart' | 'weekend' | 'monthstart' | 'monthend' | 'yearstart' | 'yearend' | 'weekbefore' |'weekafter'| 'monthbefore' | 'yearbefore' | 'yearafter'} dateType 获取特殊时间
|
|
211
|
+
* @param {string } formatter 格式字符串或预设方案数字
|
|
212
|
+
*
|
|
213
|
+
* dateType:
|
|
214
|
+
*
|
|
215
|
+
* - weekstart —— 本周起始日期
|
|
216
|
+
*
|
|
217
|
+
* - weekend —— 本周结束日期
|
|
218
|
+
*
|
|
219
|
+
* - weekbefore —— 一周前日期
|
|
220
|
+
*
|
|
221
|
+
* - weekafter —— 一周后日期
|
|
222
|
+
*
|
|
223
|
+
* - monthstart —— 本月起始日期
|
|
224
|
+
*
|
|
225
|
+
* - monthend —— 本月结束日期
|
|
226
|
+
*
|
|
227
|
+
* - monthbefore—— 一个月前日期
|
|
228
|
+
*
|
|
229
|
+
* - yearstart —— 今年1月1日
|
|
230
|
+
*
|
|
231
|
+
* - yearend —— 今年12月31日
|
|
232
|
+
*
|
|
233
|
+
* - yearbefore —— 一年前日期
|
|
234
|
+
*
|
|
235
|
+
* - yearafter —— 一年后日期
|
|
236
|
+
*
|
|
237
|
+
* formatter: 参考 getDate
|
|
238
|
+
*
|
|
239
|
+
* @returns {Date | string}
|
|
240
|
+
*/
|
|
241
|
+
const getSpecialDate = (dateType, date, formatter) => {
|
|
242
|
+
// 是否为开始时间
|
|
243
|
+
let isStart = true;
|
|
244
|
+
let time = new Date(date || getTime());
|
|
245
|
+
const setTime = () => {
|
|
246
|
+
if (isStart) {
|
|
247
|
+
time.setHours(0);
|
|
248
|
+
time.setMinutes(0);
|
|
249
|
+
time.setSeconds(0);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
time.setHours(23);
|
|
253
|
+
time.setMinutes(59);
|
|
254
|
+
time.setSeconds(59);
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
switch (dateType) {
|
|
258
|
+
case 'daybefore':
|
|
259
|
+
time = new Date(time.getTime() - 24 * 60 * 60 * 1000);
|
|
260
|
+
break;
|
|
261
|
+
case 'dayafter':
|
|
262
|
+
isStart = false;
|
|
263
|
+
time = new Date(time.getTime() + 24 * 60 * 60 * 1000);
|
|
264
|
+
break;
|
|
265
|
+
case 'weekstart':
|
|
266
|
+
time = new Date(time.getTime() - (time.getDay() - 1) * 24 * 60 * 60 * 1000);
|
|
267
|
+
break;
|
|
268
|
+
case 'weekstart7': //从周日开始
|
|
269
|
+
time = new Date(time.getTime() - time.getDay() * 24 * 60 * 60 * 1000);
|
|
270
|
+
break;
|
|
271
|
+
case 'weekend':
|
|
272
|
+
isStart = false;
|
|
273
|
+
time = new Date(time.getTime() + (7 - time.getDay()) * 24 * 60 * 60 * 1000);
|
|
274
|
+
break;
|
|
275
|
+
case 'weekbefore':
|
|
276
|
+
time = new Date(time.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
277
|
+
break;
|
|
278
|
+
case 'weekafter':
|
|
279
|
+
isStart = false;
|
|
280
|
+
time = (new Date(time.getTime() + 7 * 24 * 60 * 60 * 1000));
|
|
281
|
+
break;
|
|
282
|
+
case 'monthstart':
|
|
283
|
+
time = (new Date(time.getFullYear(), time.getMonth(), 1));
|
|
284
|
+
break;
|
|
285
|
+
case 'monthend':
|
|
286
|
+
isStart = false;
|
|
287
|
+
time = new Date(time.getFullYear(), time.getMonth() + 1, 0);
|
|
288
|
+
break;
|
|
289
|
+
case 'monthbefore':
|
|
290
|
+
time.setMonth(time.getMonth() - 1);
|
|
291
|
+
break;
|
|
292
|
+
case 'monthafter':
|
|
293
|
+
isStart = false;
|
|
294
|
+
time.setMonth(time.getMonth() + 1);
|
|
295
|
+
break;
|
|
296
|
+
case 'yearstart':
|
|
297
|
+
time.setMonth(0);
|
|
298
|
+
time.setDate(1);
|
|
299
|
+
break;
|
|
300
|
+
case 'yearend':
|
|
301
|
+
isStart = false;
|
|
302
|
+
time.setMonth(11);
|
|
303
|
+
time.setDate(31);
|
|
304
|
+
break;
|
|
305
|
+
case 'yearbefore':
|
|
306
|
+
time.setFullYear(time.getFullYear() - 1);
|
|
307
|
+
break;
|
|
308
|
+
case 'yearafter':
|
|
309
|
+
isStart = false;
|
|
310
|
+
time.setFullYear(time.getFullYear() + 1);
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
setTime();
|
|
314
|
+
return getDate(time, formatter);
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
/*
|
|
318
|
+
* @Description: 对象处理
|
|
319
|
+
* @Author: Zye
|
|
320
|
+
* @Date: 2022-09-08
|
|
321
|
+
*/
|
|
322
|
+
/**
|
|
323
|
+
* 从对象数组中获取匹配特定键值对的对象。
|
|
324
|
+
* @param objectArr 对象数组,每个对象至少包含一个键值对。
|
|
325
|
+
* @param keyName 需要匹配的键的名称。
|
|
326
|
+
* @param keyValue 需要匹配的键对应的值。可以是具体值或函数,如果为函数,则会将函数应用于数组中每个对象的键值进行匹配。
|
|
327
|
+
* @param foundKeyName 如果找到匹配的对象,从该对象中返回的键的名称。如果未指定,则返回整个对象。
|
|
328
|
+
* @returns 如果找到匹配的对象且指定了`foundKeyName`,则返回该键的值;如果未指定`foundKeyName`,则返回整个匹配的对象。如果没有找到匹配的对象,则返回一个空对象。
|
|
329
|
+
*/
|
|
330
|
+
const getObject = (objectArr, keyName, keyValue, foundKeyName) => {
|
|
331
|
+
// 使用find方法查找数组中匹配的元素,如果未找到则返回一个空对象
|
|
332
|
+
let obj = objectArr.find((v) => (typeof keyValue == 'function' ? keyValue(v[keyName]) : v[keyName] == keyValue)) || new Object();
|
|
333
|
+
// 根据是否指定了foundKeyName返回不同的结果
|
|
334
|
+
return foundKeyName ? obj[foundKeyName] : obj;
|
|
335
|
+
};
|
|
336
|
+
/**
|
|
337
|
+
* 将源对象[src]的属性分配到目标对象[dist],并递归地合并它们的属性。
|
|
338
|
+
* 如果源对象的属性是一个对象(且不是数组),则会递归地将其属性分配到目标对象的相应属性中。
|
|
339
|
+
* 如果源对象的属性是数组或其他类型,则直接覆盖目标对象的相应属性。
|
|
340
|
+
*
|
|
341
|
+
* @param dist 目标对象,其属性将被源对象的属性覆盖或合并。
|
|
342
|
+
* @param src 源对象,其属性将覆盖或合并到目标对象中。
|
|
343
|
+
* @returns 返回合并后的目标对象。
|
|
344
|
+
* @template T 目标对象和源对象的类型,该类型必须是可深度写入的对象类型。
|
|
345
|
+
*/
|
|
346
|
+
const assignObject = (dist, src) => {
|
|
347
|
+
const obj = {};
|
|
348
|
+
for (const [key, value] of Object.entries(dist)) {
|
|
349
|
+
if (typeof value !== 'object' || value === null) {
|
|
350
|
+
obj[key] = value;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
for (const [key, value] of Object.entries(src)) {
|
|
354
|
+
if (!dist[key] || typeof value !== 'object' || value === null) {
|
|
355
|
+
obj[key] = value;
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
// 如果源对象中的键值是可深度写入的对象,则递归调用assignObject函数进行合并
|
|
359
|
+
obj[key] = assignObject(dist[key], value);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return obj;
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* 此函数用来处理中间件向上透传方法 (仅用于Vue组件封装)
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
*
|
|
369
|
+
* com.vue
|
|
370
|
+
* !暴露form表单的所有方法,table表格的所有方法,以及onClick
|
|
371
|
+
* defineExpose( { onClick: () => { console.log('click') } }, formRef,tableRef)
|
|
372
|
+
* !父组件调用
|
|
373
|
+
* com.value.change() //调用表单change方法
|
|
374
|
+
* com.value.onClick() //调用onClick方法
|
|
375
|
+
*
|
|
376
|
+
* @param callback 回调函数,传onMounted
|
|
377
|
+
* @param option 默认暴露对象
|
|
378
|
+
* @param refs 要暴露的组件
|
|
379
|
+
* @returns 暴露对象
|
|
380
|
+
*/
|
|
381
|
+
const expose = (option, ...refs) => {
|
|
382
|
+
return new Proxy(option, {
|
|
383
|
+
get(_, prop) {
|
|
384
|
+
for (const ref of refs) {
|
|
385
|
+
if (ref.value && prop in ref.value) {
|
|
386
|
+
return ref.value?.[prop];
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
has(_, prop) {
|
|
391
|
+
for (const ref of refs) {
|
|
392
|
+
if (ref.value && prop in ref.value) {
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
};
|
|
400
|
+
/**
|
|
401
|
+
* 此函数用来处理中间件向上透传事件 (仅用于Vue组件封装)
|
|
402
|
+
*
|
|
403
|
+
* @param emit emit
|
|
404
|
+
* @param emitStrs
|
|
405
|
+
* @returns
|
|
406
|
+
*/
|
|
407
|
+
const on = (emit, emitStrs) => {
|
|
408
|
+
const emits = {};
|
|
409
|
+
if (!Array.isArray(emitStrs)) {
|
|
410
|
+
emitStrs = Object.keys(emitStrs);
|
|
411
|
+
}
|
|
412
|
+
emitStrs.forEach(key => {
|
|
413
|
+
emits[key] = (...args) => {
|
|
414
|
+
emit(key, ...args);
|
|
415
|
+
};
|
|
416
|
+
});
|
|
417
|
+
return emits;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
/*
|
|
421
|
+
* @Description: 逻辑处理
|
|
422
|
+
* @Author: Zye
|
|
423
|
+
* @Date: 2022-11-21
|
|
424
|
+
*/
|
|
425
|
+
const setValue = (condition, value, def = undefined) => {
|
|
426
|
+
return condition ? value : def;
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
/*
|
|
430
|
+
* @Description: 全屏
|
|
431
|
+
* @Author: Zye
|
|
432
|
+
* @Date: 2022-09-29
|
|
433
|
+
*/
|
|
434
|
+
/**
|
|
435
|
+
* 是否全屏
|
|
436
|
+
*
|
|
437
|
+
* @returns boolean
|
|
438
|
+
*/
|
|
439
|
+
function isFullscreen() {
|
|
440
|
+
return !!(document.fullscreenElement ||
|
|
441
|
+
document.mozFullScreenElement ||
|
|
442
|
+
document.webkitFullscreenElement ||
|
|
443
|
+
document.msFullscreenElement);
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* 进入全屏
|
|
447
|
+
*
|
|
448
|
+
* @param { HTMLElement } el 需要进入全屏的元素
|
|
449
|
+
*
|
|
450
|
+
*/
|
|
451
|
+
function inFullscreen(el = document.querySelector('body')) {
|
|
452
|
+
if (el.requestFullscreen) {
|
|
453
|
+
el.requestFullscreen();
|
|
454
|
+
}
|
|
455
|
+
else if (el.mozRequestFullScreen) {
|
|
456
|
+
// Firefox
|
|
457
|
+
el.mozRequestFullScreen();
|
|
458
|
+
}
|
|
459
|
+
else if (el.webkitRequestFullscreen) {
|
|
460
|
+
// Chrome, Safari, Opera
|
|
461
|
+
el.webkitRequestFullscreen();
|
|
462
|
+
}
|
|
463
|
+
else if (el.msRequestFullscreen) {
|
|
464
|
+
// IE/Edge
|
|
465
|
+
el.msRequestFullscreen();
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* 退出全屏
|
|
470
|
+
*
|
|
471
|
+
*/
|
|
472
|
+
function exitFullscreen() {
|
|
473
|
+
if (document.exitFullscreen) {
|
|
474
|
+
document.exitFullscreen();
|
|
475
|
+
}
|
|
476
|
+
else if (document.mozCancelFullScreen) {
|
|
477
|
+
// Firefox
|
|
478
|
+
document.mozCancelFullScreen();
|
|
479
|
+
}
|
|
480
|
+
else if (document.webkitExitFullscreen) {
|
|
481
|
+
// Chrome, Safari, Opera
|
|
482
|
+
document.webkitExitFullscreen();
|
|
483
|
+
}
|
|
484
|
+
else if (document.msExitFullscreen) {
|
|
485
|
+
// IE/Edge
|
|
486
|
+
document.msExitFullscreen();
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* 切换全屏显示
|
|
491
|
+
*
|
|
492
|
+
* @param { HTMLElement } el 需要进入全屏的元素
|
|
493
|
+
*/
|
|
494
|
+
function fullscreen(el = document.querySelector('body')) {
|
|
495
|
+
isFullscreen() ? exitFullscreen() : inFullscreen(el);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/*
|
|
499
|
+
* @Description: 数字处理
|
|
500
|
+
* @Author: Zye
|
|
501
|
+
* @Date: 2021-11-04
|
|
502
|
+
*/
|
|
503
|
+
/**
|
|
504
|
+
* 取近似值,取整
|
|
505
|
+
*
|
|
506
|
+
* @param num 数字
|
|
507
|
+
* @param factor 近似因子
|
|
508
|
+
* @returns 数字
|
|
509
|
+
*
|
|
510
|
+
* @ep
|
|
511
|
+
*
|
|
512
|
+
* Num(13,5) // 15
|
|
513
|
+
*
|
|
514
|
+
* Num(1.264,0.01) //1.26
|
|
515
|
+
*
|
|
516
|
+
*/
|
|
517
|
+
const Num = (num, factor) => {
|
|
518
|
+
if (!num)
|
|
519
|
+
return 0;
|
|
520
|
+
if (typeof num == 'string') {
|
|
521
|
+
num = parseFloat(num);
|
|
522
|
+
}
|
|
523
|
+
return factor ? Math.round(num / factor) * factor : num;
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* 浏览器引擎判断
|
|
528
|
+
*
|
|
529
|
+
* Gecke 火狐(Firefox)
|
|
530
|
+
* Blink (谷歌, 欧朋)
|
|
531
|
+
* WebKit (苹果,老版谷歌)
|
|
532
|
+
* Unknown (其他)
|
|
533
|
+
*/
|
|
534
|
+
function browserEngine() {
|
|
535
|
+
var userAgent = navigator.userAgent;
|
|
536
|
+
var isGecko = /Gecko\/\d+\.\d+/i.test(userAgent) && !/like Gecko/.test(userAgent);
|
|
537
|
+
var isBlink = /Chrome\/[\d.]+/.test(userAgent) && /Safari\/[\d.]+/.test(userAgent);
|
|
538
|
+
var isWebKit = /AppleWebKit\/[\d.]+/.test(userAgent) && !isBlink;
|
|
539
|
+
if (isGecko) {
|
|
540
|
+
return 'Gecko';
|
|
541
|
+
}
|
|
542
|
+
else if (isBlink) {
|
|
543
|
+
return 'Blink';
|
|
544
|
+
}
|
|
545
|
+
else if (isWebKit) {
|
|
546
|
+
return 'WebKit';
|
|
547
|
+
}
|
|
548
|
+
else {
|
|
549
|
+
return 'Unknown';
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
*
|
|
555
|
+
* @param px 像素或者数字
|
|
556
|
+
* @returns
|
|
557
|
+
*/
|
|
558
|
+
function addPx(px) {
|
|
559
|
+
return typeof px === 'number' ? px + 'px' : px;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
*
|
|
564
|
+
* @param config 配置 (如配置 baseUrl、timeout 等 )
|
|
565
|
+
* @param request 请求拦截
|
|
566
|
+
* @param response 响应成功拦截
|
|
567
|
+
* @param reject 响应错误拦截 (正常情况用不到)
|
|
568
|
+
* @returns
|
|
569
|
+
*/
|
|
570
|
+
const createHttp = ({ config = {}, request = config => config, response = data => data, reject = error => Promise.reject(error), }) => {
|
|
571
|
+
// 创建Axios
|
|
572
|
+
const axiosClone = axios.create({ timeout: 1000 * 60 * 5, ...(config || {}) });
|
|
573
|
+
// 请求
|
|
574
|
+
axiosClone.interceptors.request.use((config) => {
|
|
575
|
+
return request(config);
|
|
576
|
+
});
|
|
577
|
+
// 响应
|
|
578
|
+
axiosClone.interceptors.response.use((res) => {
|
|
579
|
+
// 处理文件
|
|
580
|
+
const contentType = res.headers['content-type'];
|
|
581
|
+
if ((contentType && contentType.includes('application/octet-stream')) || contentType.includes('file'))
|
|
582
|
+
return res.data;
|
|
583
|
+
// 处理数据
|
|
584
|
+
return response(res.data, res);
|
|
585
|
+
}, (error) => {
|
|
586
|
+
return Promise.reject(reject(error));
|
|
587
|
+
});
|
|
588
|
+
// 重写http
|
|
589
|
+
const http = (config) => {
|
|
590
|
+
return axiosClone(config);
|
|
591
|
+
};
|
|
592
|
+
const get = (method) => {
|
|
593
|
+
return http[method] = (url, params = {}, config = {}) => {
|
|
594
|
+
return axiosClone[method](url, {
|
|
595
|
+
...config,
|
|
596
|
+
params,
|
|
597
|
+
});
|
|
598
|
+
};
|
|
599
|
+
};
|
|
600
|
+
const post = (method) => {
|
|
601
|
+
return http[method] = (url, data = {}, config = {}) => {
|
|
602
|
+
return axiosClone[method](url, data, config);
|
|
603
|
+
};
|
|
604
|
+
};
|
|
605
|
+
http.get = get('get');
|
|
606
|
+
http.delete = get('delete');
|
|
607
|
+
http.head = get('head');
|
|
608
|
+
http.post = post('post');
|
|
609
|
+
http.put = post('put');
|
|
610
|
+
http.patch = post('patch');
|
|
611
|
+
return http;
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
let trimLeft = /^\s+/;
|
|
615
|
+
let trimRight = /\s+$/;
|
|
616
|
+
let mathRound = Math.round;
|
|
617
|
+
let mathMin = Math.min;
|
|
618
|
+
let mathMax = Math.max;
|
|
619
|
+
let mathRandom = Math.random;
|
|
620
|
+
class TinyColor {
|
|
621
|
+
matchers;
|
|
622
|
+
names;
|
|
623
|
+
_originalInput;
|
|
624
|
+
_r;
|
|
625
|
+
_g;
|
|
626
|
+
_b;
|
|
627
|
+
_a;
|
|
628
|
+
_roundA;
|
|
629
|
+
_format;
|
|
630
|
+
_gradientType;
|
|
631
|
+
_ok;
|
|
632
|
+
isDark;
|
|
633
|
+
isLight;
|
|
634
|
+
isValid;
|
|
635
|
+
constructor(color, opts) {
|
|
636
|
+
// If input is already a tinycolor, return itself
|
|
637
|
+
if (color instanceof TinyColor) {
|
|
638
|
+
return color;
|
|
639
|
+
}
|
|
640
|
+
this.init(color, opts);
|
|
641
|
+
}
|
|
642
|
+
init(color, opts) {
|
|
643
|
+
this.matchers = this.initMatchers();
|
|
644
|
+
this.names = TinyColor.initNames();
|
|
645
|
+
const rgb = this.inputToRGB(color);
|
|
646
|
+
this._originalInput = typeof color !== 'undefined' ? color : '';
|
|
647
|
+
this._r = rgb.r;
|
|
648
|
+
this._g = rgb.g;
|
|
649
|
+
this._b = rgb.b;
|
|
650
|
+
this._a = rgb.a;
|
|
651
|
+
this._roundA = mathRound(100 * this._a) / 100;
|
|
652
|
+
// this._format = typeof opts !== 'undefined' && typeof opts.format !== 'undefined' ? opts.format : rgb.format || ''
|
|
653
|
+
this._format = opts?.format || rgb?.format || '';
|
|
654
|
+
// this._gradientType = typeof opts !== 'undefined' && typeof opts.gradientType !== 'undefined' ? opts.gradientType : ''
|
|
655
|
+
this._gradientType = opts?.gradientType || '';
|
|
656
|
+
// Don't let the range of [0,255] come back in [0,1].
|
|
657
|
+
// Potentially lose a little bit of precision here, but will fix issues where
|
|
658
|
+
// .5 gets interpreted as half of the total, instead of half of 1
|
|
659
|
+
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
|
|
660
|
+
if (this._r < 1) {
|
|
661
|
+
this._r = mathRound(this._r);
|
|
662
|
+
}
|
|
663
|
+
if (this._g < 1) {
|
|
664
|
+
this._g = mathRound(this._g);
|
|
665
|
+
}
|
|
666
|
+
if (this._b < 1) {
|
|
667
|
+
this._b = mathRound(this._b);
|
|
668
|
+
}
|
|
669
|
+
this._ok = rgb.ok;
|
|
670
|
+
this.initAttr();
|
|
671
|
+
}
|
|
672
|
+
initAttr() {
|
|
673
|
+
this.isDark = this.getBrightness() < 128;
|
|
674
|
+
this.isLight = !this.isDark;
|
|
675
|
+
this.isValid = this._ok;
|
|
676
|
+
}
|
|
677
|
+
static initNames() {
|
|
678
|
+
// Big List of Colors
|
|
679
|
+
// ------------------
|
|
680
|
+
// <http://www.w3.org/TR/css3-color/#svg-color>
|
|
681
|
+
return {
|
|
682
|
+
aliceblue: 'f0f8ff',
|
|
683
|
+
antiquewhite: 'faebd7',
|
|
684
|
+
aqua: '0ff',
|
|
685
|
+
aquamarine: '7fffd4',
|
|
686
|
+
azure: 'f0ffff',
|
|
687
|
+
beige: 'f5f5dc',
|
|
688
|
+
bisque: 'ffe4c4',
|
|
689
|
+
black: '000',
|
|
690
|
+
blanchedalmond: 'ffebcd',
|
|
691
|
+
blue: '00f',
|
|
692
|
+
blueviolet: '8a2be2',
|
|
693
|
+
brown: 'a52a2a',
|
|
694
|
+
burlywood: 'deb887',
|
|
695
|
+
burntsienna: 'ea7e5d',
|
|
696
|
+
cadetblue: '5f9ea0',
|
|
697
|
+
chartreuse: '7fff00',
|
|
698
|
+
chocolate: 'd2691e',
|
|
699
|
+
coral: 'ff7f50',
|
|
700
|
+
cornflowerblue: '6495ed',
|
|
701
|
+
cornsilk: 'fff8dc',
|
|
702
|
+
crimson: 'dc143c',
|
|
703
|
+
cyan: '0ff',
|
|
704
|
+
darkblue: '00008b',
|
|
705
|
+
darkcyan: '008b8b',
|
|
706
|
+
darkgoldenrod: 'b8860b',
|
|
707
|
+
darkgray: 'a9a9a9',
|
|
708
|
+
darkgreen: '006400',
|
|
709
|
+
darkgrey: 'a9a9a9',
|
|
710
|
+
darkkhaki: 'bdb76b',
|
|
711
|
+
darkmagenta: '8b008b',
|
|
712
|
+
darkolivegreen: '556b2f',
|
|
713
|
+
darkorange: 'ff8c00',
|
|
714
|
+
darkorchid: '9932cc',
|
|
715
|
+
darkred: '8b0000',
|
|
716
|
+
darksalmon: 'e9967a',
|
|
717
|
+
darkseagreen: '8fbc8f',
|
|
718
|
+
darkslateblue: '483d8b',
|
|
719
|
+
darkslategray: '2f4f4f',
|
|
720
|
+
darkslategrey: '2f4f4f',
|
|
721
|
+
darkturquoise: '00ced1',
|
|
722
|
+
darkviolet: '9400d3',
|
|
723
|
+
deeppink: 'ff1493',
|
|
724
|
+
deepskyblue: '00bfff',
|
|
725
|
+
dimgray: '696969',
|
|
726
|
+
dimgrey: '696969',
|
|
727
|
+
dodgerblue: '1e90ff',
|
|
728
|
+
firebrick: 'b22222',
|
|
729
|
+
floralwhite: 'fffaf0',
|
|
730
|
+
forestgreen: '228b22',
|
|
731
|
+
fuchsia: 'f0f',
|
|
732
|
+
gainsboro: 'dcdcdc',
|
|
733
|
+
ghostwhite: 'f8f8ff',
|
|
734
|
+
gold: 'ffd700',
|
|
735
|
+
goldenrod: 'daa520',
|
|
736
|
+
gray: '808080',
|
|
737
|
+
green: '008000',
|
|
738
|
+
greenyellow: 'adff2f',
|
|
739
|
+
grey: '808080',
|
|
740
|
+
honeydew: 'f0fff0',
|
|
741
|
+
hotpink: 'ff69b4',
|
|
742
|
+
indianred: 'cd5c5c',
|
|
743
|
+
indigo: '4b0082',
|
|
744
|
+
ivory: 'fffff0',
|
|
745
|
+
khaki: 'f0e68c',
|
|
746
|
+
lavender: 'e6e6fa',
|
|
747
|
+
lavenderblush: 'fff0f5',
|
|
748
|
+
lawngreen: '7cfc00',
|
|
749
|
+
lemonchiffon: 'fffacd',
|
|
750
|
+
lightblue: 'add8e6',
|
|
751
|
+
lightcoral: 'f08080',
|
|
752
|
+
lightcyan: 'e0ffff',
|
|
753
|
+
lightgoldenrodyellow: 'fafad2',
|
|
754
|
+
lightgray: 'd3d3d3',
|
|
755
|
+
lightgreen: '90ee90',
|
|
756
|
+
lightgrey: 'd3d3d3',
|
|
757
|
+
lightpink: 'ffb6c1',
|
|
758
|
+
lightsalmon: 'ffa07a',
|
|
759
|
+
lightseagreen: '20b2aa',
|
|
760
|
+
lightskyblue: '87cefa',
|
|
761
|
+
lightslategray: '789',
|
|
762
|
+
lightslategrey: '789',
|
|
763
|
+
lightsteelblue: 'b0c4de',
|
|
764
|
+
lightyellow: 'ffffe0',
|
|
765
|
+
lime: '0f0',
|
|
766
|
+
limegreen: '32cd32',
|
|
767
|
+
linen: 'faf0e6',
|
|
768
|
+
magenta: 'f0f',
|
|
769
|
+
maroon: '800000',
|
|
770
|
+
mediumaquamarine: '66cdaa',
|
|
771
|
+
mediumblue: '0000cd',
|
|
772
|
+
mediumorchid: 'ba55d3',
|
|
773
|
+
mediumpurple: '9370db',
|
|
774
|
+
mediumseagreen: '3cb371',
|
|
775
|
+
mediumslateblue: '7b68ee',
|
|
776
|
+
mediumspringgreen: '00fa9a',
|
|
777
|
+
mediumturquoise: '48d1cc',
|
|
778
|
+
mediumvioletred: 'c71585',
|
|
779
|
+
midnightblue: '191970',
|
|
780
|
+
mintcream: 'f5fffa',
|
|
781
|
+
mistyrose: 'ffe4e1',
|
|
782
|
+
moccasin: 'ffe4b5',
|
|
783
|
+
navajowhite: 'ffdead',
|
|
784
|
+
navy: '000080',
|
|
785
|
+
oldlace: 'fdf5e6',
|
|
786
|
+
olive: '808000',
|
|
787
|
+
olivedrab: '6b8e23',
|
|
788
|
+
orange: 'ffa500',
|
|
789
|
+
orangered: 'ff4500',
|
|
790
|
+
orchid: 'da70d6',
|
|
791
|
+
palegoldenrod: 'eee8aa',
|
|
792
|
+
palegreen: '98fb98',
|
|
793
|
+
paleturquoise: 'afeeee',
|
|
794
|
+
palevioletred: 'db7093',
|
|
795
|
+
papayawhip: 'ffefd5',
|
|
796
|
+
peachpuff: 'ffdab9',
|
|
797
|
+
peru: 'cd853f',
|
|
798
|
+
pink: 'ffc0cb',
|
|
799
|
+
plum: 'dda0dd',
|
|
800
|
+
powderblue: 'b0e0e6',
|
|
801
|
+
purple: '800080',
|
|
802
|
+
rebeccapurple: '663399',
|
|
803
|
+
red: 'f00',
|
|
804
|
+
rosybrown: 'bc8f8f',
|
|
805
|
+
royalblue: '4169e1',
|
|
806
|
+
saddlebrown: '8b4513',
|
|
807
|
+
salmon: 'fa8072',
|
|
808
|
+
sandybrown: 'f4a460',
|
|
809
|
+
seagreen: '2e8b57',
|
|
810
|
+
seashell: 'fff5ee',
|
|
811
|
+
sienna: 'a0522d',
|
|
812
|
+
silver: 'c0c0c0',
|
|
813
|
+
skyblue: '87ceeb',
|
|
814
|
+
slateblue: '6a5acd',
|
|
815
|
+
slategray: '708090',
|
|
816
|
+
slategrey: '708090',
|
|
817
|
+
snow: 'fffafa',
|
|
818
|
+
springgreen: '00ff7f',
|
|
819
|
+
steelblue: '4682b4',
|
|
820
|
+
tan: 'd2b48c',
|
|
821
|
+
teal: '008080',
|
|
822
|
+
thistle: 'd8bfd8',
|
|
823
|
+
tomato: 'ff6347',
|
|
824
|
+
turquoise: '40e0d0',
|
|
825
|
+
violet: 'ee82ee',
|
|
826
|
+
wheat: 'f5deb3',
|
|
827
|
+
white: 'fff',
|
|
828
|
+
whitesmoke: 'f5f5f5',
|
|
829
|
+
yellow: 'ff0',
|
|
830
|
+
yellowgreen: '9acd32',
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
initMatchers() {
|
|
834
|
+
// <http://www.w3.org/TR/css3-values/#integers>
|
|
835
|
+
const CSS_INTEGER = '[-\\+]?\\d+%?';
|
|
836
|
+
// <http://www.w3.org/TR/css3-values/#number-value>
|
|
837
|
+
const CSS_NUMBER = '[-\\+]?\\d*\\.\\d+%?';
|
|
838
|
+
// Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
|
|
839
|
+
const CSS_UNIT = '(?:' + CSS_NUMBER + ')|(?:' + CSS_INTEGER + ')';
|
|
840
|
+
// Actual matching.
|
|
841
|
+
// Parentheses and commas are optional, but not required.
|
|
842
|
+
// Whitespace can take the place of commas or opening paren
|
|
843
|
+
const PERMISSIVE_MATCH3 = '[\\s|\\(]+(' + CSS_UNIT + ')[,|\\s]+(' + CSS_UNIT + ')[,|\\s]+(' + CSS_UNIT + ')\\s*\\)?';
|
|
844
|
+
const PERMISSIVE_MATCH4 = '[\\s|\\(]+(' + CSS_UNIT + ')[,|\\s]+(' + CSS_UNIT + ')[,|\\s]+(' + CSS_UNIT + ')[,|\\s]+(' + CSS_UNIT + ')\\s*\\)?';
|
|
845
|
+
return {
|
|
846
|
+
CSS_UNIT: new RegExp(CSS_UNIT),
|
|
847
|
+
rgb: new RegExp('rgb' + PERMISSIVE_MATCH3),
|
|
848
|
+
rgba: new RegExp('rgba' + PERMISSIVE_MATCH4),
|
|
849
|
+
hsl: new RegExp('hsl' + PERMISSIVE_MATCH3),
|
|
850
|
+
hsla: new RegExp('hsla' + PERMISSIVE_MATCH4),
|
|
851
|
+
hsv: new RegExp('hsv' + PERMISSIVE_MATCH3),
|
|
852
|
+
hsva: new RegExp('hsva' + PERMISSIVE_MATCH4),
|
|
853
|
+
hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
|
854
|
+
hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
|
855
|
+
hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
|
856
|
+
hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
getBrightness() {
|
|
860
|
+
//http://www.w3.org/TR/AERT#color-contrast
|
|
861
|
+
const rgb = this.toRgb();
|
|
862
|
+
return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
|
|
863
|
+
}
|
|
864
|
+
toRgb() {
|
|
865
|
+
return {
|
|
866
|
+
r: mathRound(this._r),
|
|
867
|
+
g: mathRound(this._g),
|
|
868
|
+
b: mathRound(this._b),
|
|
869
|
+
a: this._a,
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
static getNames() {
|
|
873
|
+
return this.initNames();
|
|
874
|
+
}
|
|
875
|
+
getOriginalInput() {
|
|
876
|
+
return this._originalInput;
|
|
877
|
+
}
|
|
878
|
+
getFormat() {
|
|
879
|
+
return this._format;
|
|
880
|
+
}
|
|
881
|
+
getAlpha() {
|
|
882
|
+
return this._a;
|
|
883
|
+
}
|
|
884
|
+
getLuminance() {
|
|
885
|
+
//http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
|
886
|
+
const rgb = this.toRgb();
|
|
887
|
+
let RsRGB, GsRGB, BsRGB, R, G, B;
|
|
888
|
+
RsRGB = rgb.r / 255;
|
|
889
|
+
GsRGB = rgb.g / 255;
|
|
890
|
+
BsRGB = rgb.b / 255;
|
|
891
|
+
if (RsRGB <= 0.03928) {
|
|
892
|
+
R = RsRGB / 12.92;
|
|
893
|
+
}
|
|
894
|
+
else {
|
|
895
|
+
R = Math.pow((RsRGB + 0.055) / 1.055, 2.4);
|
|
896
|
+
}
|
|
897
|
+
if (GsRGB <= 0.03928) {
|
|
898
|
+
G = GsRGB / 12.92;
|
|
899
|
+
}
|
|
900
|
+
else {
|
|
901
|
+
G = Math.pow((GsRGB + 0.055) / 1.055, 2.4);
|
|
902
|
+
}
|
|
903
|
+
if (BsRGB <= 0.03928) {
|
|
904
|
+
B = BsRGB / 12.92;
|
|
905
|
+
}
|
|
906
|
+
else {
|
|
907
|
+
B = Math.pow((BsRGB + 0.055) / 1.055, 2.4);
|
|
908
|
+
}
|
|
909
|
+
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
|
|
910
|
+
}
|
|
911
|
+
setAlpha(value) {
|
|
912
|
+
this._a = this.boundAlpha(value);
|
|
913
|
+
this._roundA = mathRound(100 * this._a) / 100;
|
|
914
|
+
return this;
|
|
915
|
+
}
|
|
916
|
+
toHsv() {
|
|
917
|
+
let hsv = this.rgbToHsv(this._r, this._g, this._b);
|
|
918
|
+
return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
|
|
919
|
+
}
|
|
920
|
+
toHsvString() {
|
|
921
|
+
let hsv = this.rgbToHsv(this._r, this._g, this._b);
|
|
922
|
+
let h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
|
|
923
|
+
return this._a == 1 ? 'hsv(' + h + ', ' + s + '%, ' + v + '%)' : 'hsva(' + h + ', ' + s + '%, ' + v + '%, ' + this._roundA + ')';
|
|
924
|
+
}
|
|
925
|
+
toHsl() {
|
|
926
|
+
let hsl = this.rgbToHsl(this._r, this._g, this._b);
|
|
927
|
+
return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
|
|
928
|
+
}
|
|
929
|
+
toHslString() {
|
|
930
|
+
let hsl = this.rgbToHsl(this._r, this._g, this._b);
|
|
931
|
+
let h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
|
|
932
|
+
return this._a == 1 ? 'hsl(' + h + ', ' + s + '%, ' + l + '%)' : 'hsla(' + h + ', ' + s + '%, ' + l + '%, ' + this._roundA + ')';
|
|
933
|
+
}
|
|
934
|
+
toHex(allow3Char) {
|
|
935
|
+
return this.rgbToHex(this._r, this._g, this._b, allow3Char);
|
|
936
|
+
}
|
|
937
|
+
toHexString(allow3Char) {
|
|
938
|
+
return '#' + this.toHex(allow3Char);
|
|
939
|
+
}
|
|
940
|
+
toHex8(allow4Char) {
|
|
941
|
+
return this.rgbaToHex(this._r, this._g, this._b, this._a, allow4Char);
|
|
942
|
+
}
|
|
943
|
+
toHex8String(allow4Char) {
|
|
944
|
+
return '#' + this.toHex8(allow4Char);
|
|
945
|
+
}
|
|
946
|
+
toRgbString() {
|
|
947
|
+
return this._a == 1
|
|
948
|
+
? 'rgb(' + mathRound(this._r) + ', ' + mathRound(this._g) + ', ' + mathRound(this._b) + ')'
|
|
949
|
+
: 'rgba(' + mathRound(this._r) + ', ' + mathRound(this._g) + ', ' + mathRound(this._b) + ', ' + this._roundA + ')';
|
|
950
|
+
}
|
|
951
|
+
toPercentageRgb() {
|
|
952
|
+
return {
|
|
953
|
+
r: mathRound(this.bound01(this._r, 255) * 100) + '%',
|
|
954
|
+
g: mathRound(this.bound01(this._g, 255) * 100) + '%',
|
|
955
|
+
b: mathRound(this.bound01(this._b, 255) * 100) + '%',
|
|
956
|
+
a: this._a,
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
toPercentageRgbString() {
|
|
960
|
+
return this._a == 1
|
|
961
|
+
? 'rgb(' +
|
|
962
|
+
mathRound(this.bound01(this._r, 255) * 100) +
|
|
963
|
+
'%, ' +
|
|
964
|
+
mathRound(this.bound01(this._g, 255) * 100) +
|
|
965
|
+
'%, ' +
|
|
966
|
+
mathRound(this.bound01(this._b, 255) * 100) +
|
|
967
|
+
'%)'
|
|
968
|
+
: 'rgba(' +
|
|
969
|
+
mathRound(this.bound01(this._r, 255) * 100) +
|
|
970
|
+
'%, ' +
|
|
971
|
+
mathRound(this.bound01(this._g, 255) * 100) +
|
|
972
|
+
'%, ' +
|
|
973
|
+
mathRound(this.bound01(this._b, 255) * 100) +
|
|
974
|
+
'%, ' +
|
|
975
|
+
this._roundA +
|
|
976
|
+
')';
|
|
977
|
+
}
|
|
978
|
+
toName() {
|
|
979
|
+
if (this._a === 0) {
|
|
980
|
+
return 'transparent';
|
|
981
|
+
}
|
|
982
|
+
if (this._a < 1) {
|
|
983
|
+
return false;
|
|
984
|
+
}
|
|
985
|
+
return this._flip()[this.rgbToHex(this._r, this._g, this._b, true)] || false;
|
|
986
|
+
}
|
|
987
|
+
toFilter(secondColor) {
|
|
988
|
+
let hex8String = '#' + this.rgbaToArgbHex(this._r, this._g, this._b, this._a);
|
|
989
|
+
let secondHex8String = hex8String;
|
|
990
|
+
let gradientType = this._gradientType ? 'GradientType = 1, ' : '';
|
|
991
|
+
if (secondColor) {
|
|
992
|
+
const tinyColorObj = new TinyColor(secondColor);
|
|
993
|
+
secondHex8String = '#' + this.rgbaToArgbHex(tinyColorObj._r, tinyColorObj._g, tinyColorObj._b, tinyColorObj._a);
|
|
994
|
+
}
|
|
995
|
+
return ('progid:DXImageTransform.Microsoft.gradient(' +
|
|
996
|
+
gradientType +
|
|
997
|
+
'startColorstr=' +
|
|
998
|
+
hex8String +
|
|
999
|
+
',endColorstr=' +
|
|
1000
|
+
secondHex8String +
|
|
1001
|
+
')');
|
|
1002
|
+
}
|
|
1003
|
+
toString(format) {
|
|
1004
|
+
let formatSet = !!format;
|
|
1005
|
+
format = format || this._format;
|
|
1006
|
+
let formattedString = '';
|
|
1007
|
+
let hasAlpha = this._a < 1 && this._a >= 0;
|
|
1008
|
+
let needsAlphaFormat = !formatSet &&
|
|
1009
|
+
hasAlpha &&
|
|
1010
|
+
(format === 'hex' || format === 'hex6' || format === 'hex3' || format === 'hex4' || format === 'hex8' || format === 'name');
|
|
1011
|
+
if (needsAlphaFormat) {
|
|
1012
|
+
if (format === 'name' && this._a === 0) {
|
|
1013
|
+
return this.toName();
|
|
1014
|
+
}
|
|
1015
|
+
return this.toRgbString();
|
|
1016
|
+
}
|
|
1017
|
+
if (format === 'rgb') {
|
|
1018
|
+
formattedString = this.toRgbString();
|
|
1019
|
+
}
|
|
1020
|
+
if (format === 'prgb') {
|
|
1021
|
+
formattedString = this.toPercentageRgbString();
|
|
1022
|
+
}
|
|
1023
|
+
if (format === 'hex' || format === 'hex6') {
|
|
1024
|
+
formattedString = this.toHexString();
|
|
1025
|
+
}
|
|
1026
|
+
if (format === 'hex3') {
|
|
1027
|
+
formattedString = this.toHexString(true);
|
|
1028
|
+
}
|
|
1029
|
+
if (format === 'hex4') {
|
|
1030
|
+
formattedString = this.toHex8String(true);
|
|
1031
|
+
}
|
|
1032
|
+
if (format === 'hex8') {
|
|
1033
|
+
formattedString = this.toHex8String();
|
|
1034
|
+
}
|
|
1035
|
+
if (format === 'name') {
|
|
1036
|
+
formattedString = this.toName();
|
|
1037
|
+
}
|
|
1038
|
+
if (format === 'hsl') {
|
|
1039
|
+
formattedString = this.toHslString();
|
|
1040
|
+
}
|
|
1041
|
+
if (format === 'hsv') {
|
|
1042
|
+
formattedString = this.toHsvString();
|
|
1043
|
+
}
|
|
1044
|
+
return formattedString || this.toHexString();
|
|
1045
|
+
}
|
|
1046
|
+
clone() {
|
|
1047
|
+
return new TinyColor(this.toString());
|
|
1048
|
+
}
|
|
1049
|
+
_applyModification(fn, args) {
|
|
1050
|
+
let color = fn.apply(null, [this].concat([].slice.call(args)));
|
|
1051
|
+
this._r = color._r;
|
|
1052
|
+
this._g = color._g;
|
|
1053
|
+
this._b = color._b;
|
|
1054
|
+
this.setAlpha(color._a);
|
|
1055
|
+
return this;
|
|
1056
|
+
}
|
|
1057
|
+
_lighten(color, amount) {
|
|
1058
|
+
amount = amount === 0 ? 0 : amount || 10;
|
|
1059
|
+
let hsl = new TinyColor(color).toHsl();
|
|
1060
|
+
hsl.l += amount / 100;
|
|
1061
|
+
hsl.l = color.clamp01(hsl.l);
|
|
1062
|
+
return new TinyColor(hsl);
|
|
1063
|
+
}
|
|
1064
|
+
lighten(...args) {
|
|
1065
|
+
return this._applyModification(this._lighten, args);
|
|
1066
|
+
}
|
|
1067
|
+
_brighten(color, amount) {
|
|
1068
|
+
amount = amount === 0 ? 0 : amount || 10;
|
|
1069
|
+
let rgb = new TinyColor(color).toRgb();
|
|
1070
|
+
rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * -(amount / 100))));
|
|
1071
|
+
rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * -(amount / 100))));
|
|
1072
|
+
rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * -(amount / 100))));
|
|
1073
|
+
return new TinyColor(rgb);
|
|
1074
|
+
}
|
|
1075
|
+
brighten(...args) {
|
|
1076
|
+
return this._applyModification(this._brighten, args);
|
|
1077
|
+
}
|
|
1078
|
+
_darken(color, amount) {
|
|
1079
|
+
amount = amount === 0 ? 0 : amount || 10;
|
|
1080
|
+
let hsl = new TinyColor(color).toHsl();
|
|
1081
|
+
hsl.l -= amount / 100;
|
|
1082
|
+
hsl.l = color.clamp01(hsl.l);
|
|
1083
|
+
return new TinyColor(hsl);
|
|
1084
|
+
}
|
|
1085
|
+
darken(...args) {
|
|
1086
|
+
return this._applyModification(this._darken, args);
|
|
1087
|
+
}
|
|
1088
|
+
_desaturate(color, amount) {
|
|
1089
|
+
amount = amount === 0 ? 0 : amount || 10;
|
|
1090
|
+
let hsl = new TinyColor(color).toHsl();
|
|
1091
|
+
hsl.s -= amount / 100;
|
|
1092
|
+
hsl.s = color.clamp01(hsl.s);
|
|
1093
|
+
return new TinyColor(hsl);
|
|
1094
|
+
}
|
|
1095
|
+
desaturate(...args) {
|
|
1096
|
+
return this._applyModification(this._desaturate, args);
|
|
1097
|
+
}
|
|
1098
|
+
_saturate(color, amount) {
|
|
1099
|
+
amount = amount === 0 ? 0 : amount || 10;
|
|
1100
|
+
let hsl = new TinyColor(color).toHsl();
|
|
1101
|
+
hsl.s += amount / 100;
|
|
1102
|
+
hsl.s = color.clamp01(hsl.s);
|
|
1103
|
+
return new TinyColor(hsl);
|
|
1104
|
+
}
|
|
1105
|
+
saturate(...args) {
|
|
1106
|
+
return this._applyModification(this._saturate, args);
|
|
1107
|
+
}
|
|
1108
|
+
_greyscale(color) {
|
|
1109
|
+
return new TinyColor(color).desaturate(100);
|
|
1110
|
+
}
|
|
1111
|
+
greyscale(...args) {
|
|
1112
|
+
return this._applyModification(this._greyscale, args);
|
|
1113
|
+
}
|
|
1114
|
+
_spin(color, amount) {
|
|
1115
|
+
let hsl = new TinyColor(color).toHsl();
|
|
1116
|
+
let hue = (hsl.h + amount) % 360;
|
|
1117
|
+
hsl.h = hue < 0 ? 360 + hue : hue;
|
|
1118
|
+
return new TinyColor(hsl);
|
|
1119
|
+
}
|
|
1120
|
+
spin(...args) {
|
|
1121
|
+
return this._applyModification(this._spin, args);
|
|
1122
|
+
}
|
|
1123
|
+
_applyCombination(fn, args) {
|
|
1124
|
+
return fn.apply(null, [this].concat([].slice.call(args)));
|
|
1125
|
+
}
|
|
1126
|
+
_analogous(color, results, slices) {
|
|
1127
|
+
results = results || 6;
|
|
1128
|
+
slices = slices || 30;
|
|
1129
|
+
let hsl = new TinyColor(color).toHsl();
|
|
1130
|
+
let part = 360 / slices;
|
|
1131
|
+
let ret = [new TinyColor(color)];
|
|
1132
|
+
for (hsl.h = (hsl.h - ((part * results) >> 1) + 720) % 360; --results;) {
|
|
1133
|
+
hsl.h = (hsl.h + part) % 360;
|
|
1134
|
+
ret.push(new TinyColor(hsl));
|
|
1135
|
+
}
|
|
1136
|
+
return ret;
|
|
1137
|
+
}
|
|
1138
|
+
analogous(...args) {
|
|
1139
|
+
return this._applyCombination(this._analogous, args);
|
|
1140
|
+
}
|
|
1141
|
+
_complement(color) {
|
|
1142
|
+
let hsl = new TinyColor(color).toHsl();
|
|
1143
|
+
hsl.h = (hsl.h + 180) % 360;
|
|
1144
|
+
return new TinyColor(hsl);
|
|
1145
|
+
}
|
|
1146
|
+
complement(...args) {
|
|
1147
|
+
return this._applyCombination(this._complement, args);
|
|
1148
|
+
}
|
|
1149
|
+
_monochromatic(color, results) {
|
|
1150
|
+
results = results || 6;
|
|
1151
|
+
let hsv = new TinyColor(color).toHsv();
|
|
1152
|
+
let h = hsv.h, s = hsv.s, v = hsv.v;
|
|
1153
|
+
let ret = [];
|
|
1154
|
+
let modification = 1 / results;
|
|
1155
|
+
while (results--) {
|
|
1156
|
+
ret.push(new TinyColor({ h: h, s: s, v: v }));
|
|
1157
|
+
v = (v + modification) % 1;
|
|
1158
|
+
}
|
|
1159
|
+
return ret;
|
|
1160
|
+
}
|
|
1161
|
+
monochromatic(...args) {
|
|
1162
|
+
return this._applyCombination(this._monochromatic, args);
|
|
1163
|
+
}
|
|
1164
|
+
_splitcomplement(color) {
|
|
1165
|
+
let hsl = new TinyColor(color).toHsl();
|
|
1166
|
+
let h = hsl.h;
|
|
1167
|
+
return [
|
|
1168
|
+
new TinyColor(color),
|
|
1169
|
+
new TinyColor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l }),
|
|
1170
|
+
new TinyColor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l }),
|
|
1171
|
+
];
|
|
1172
|
+
}
|
|
1173
|
+
splitcomplement(...args) {
|
|
1174
|
+
return this._applyCombination(this._splitcomplement, args);
|
|
1175
|
+
}
|
|
1176
|
+
_triad(color) {
|
|
1177
|
+
let hsl = new TinyColor(color).toHsl();
|
|
1178
|
+
let h = hsl.h;
|
|
1179
|
+
return [
|
|
1180
|
+
new TinyColor(color),
|
|
1181
|
+
new TinyColor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
|
|
1182
|
+
new TinyColor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }),
|
|
1183
|
+
];
|
|
1184
|
+
}
|
|
1185
|
+
triad(...args) {
|
|
1186
|
+
return this._applyCombination(this._triad, args);
|
|
1187
|
+
}
|
|
1188
|
+
_tetrad(obj) {
|
|
1189
|
+
let hsl = new TinyColor(obj).toHsl();
|
|
1190
|
+
let h = hsl.h;
|
|
1191
|
+
return [
|
|
1192
|
+
new TinyColor(obj),
|
|
1193
|
+
new TinyColor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
|
|
1194
|
+
new TinyColor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
|
|
1195
|
+
new TinyColor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }),
|
|
1196
|
+
];
|
|
1197
|
+
}
|
|
1198
|
+
tetrad(...args) {
|
|
1199
|
+
return this._applyCombination(this._tetrad, args);
|
|
1200
|
+
}
|
|
1201
|
+
static fromRatio(color, opts) {
|
|
1202
|
+
if (typeof color == 'object') {
|
|
1203
|
+
let newColor = {};
|
|
1204
|
+
for (let i in color) {
|
|
1205
|
+
if (color.hasOwnProperty(i)) {
|
|
1206
|
+
if (i === 'a') {
|
|
1207
|
+
newColor[i] = color[i];
|
|
1208
|
+
}
|
|
1209
|
+
else {
|
|
1210
|
+
newColor[i] = TinyColor.convertToPercentage(color[i]);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
color = newColor;
|
|
1215
|
+
}
|
|
1216
|
+
return new TinyColor(color, opts);
|
|
1217
|
+
}
|
|
1218
|
+
static equals(color1, color2) {
|
|
1219
|
+
if (!color1 || !color2) {
|
|
1220
|
+
return false;
|
|
1221
|
+
}
|
|
1222
|
+
return new TinyColor(color1).toRgbString() == new TinyColor(color2).toRgbString();
|
|
1223
|
+
}
|
|
1224
|
+
static random() {
|
|
1225
|
+
return TinyColor.fromRatio({
|
|
1226
|
+
r: mathRandom(),
|
|
1227
|
+
g: mathRandom(),
|
|
1228
|
+
b: mathRandom(),
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
static mix(color1, color2, amount) {
|
|
1232
|
+
amount = amount === 0 ? 0 : amount || 50;
|
|
1233
|
+
let rgb1 = new TinyColor(color1).toRgb();
|
|
1234
|
+
let rgb2 = new TinyColor(color2).toRgb();
|
|
1235
|
+
let p = amount / 100;
|
|
1236
|
+
let rgba = {
|
|
1237
|
+
r: (rgb2.r - rgb1.r) * p + rgb1.r,
|
|
1238
|
+
g: (rgb2.g - rgb1.g) * p + rgb1.g,
|
|
1239
|
+
b: (rgb2.b - rgb1.b) * p + rgb1.b,
|
|
1240
|
+
a: (rgb2.a - rgb1.a) * p + rgb1.a,
|
|
1241
|
+
};
|
|
1242
|
+
return new TinyColor(rgba);
|
|
1243
|
+
}
|
|
1244
|
+
static readability(color1, color2) {
|
|
1245
|
+
let c1 = new TinyColor(color1);
|
|
1246
|
+
let c2 = new TinyColor(color2);
|
|
1247
|
+
return (Math.max(c1.getLuminance(), c2.getLuminance()) + 0.05) / (Math.min(c1.getLuminance(), c2.getLuminance()) + 0.05);
|
|
1248
|
+
}
|
|
1249
|
+
static isReadable(color1, color2, wcag2) {
|
|
1250
|
+
let readability = TinyColor.readability(color1, color2);
|
|
1251
|
+
let wcag2Parms, out;
|
|
1252
|
+
out = false;
|
|
1253
|
+
wcag2Parms = TinyColor.validateWCAG2Parms(wcag2);
|
|
1254
|
+
switch (wcag2Parms.level + wcag2Parms.size) {
|
|
1255
|
+
case 'AAsmall':
|
|
1256
|
+
case 'AAAlarge':
|
|
1257
|
+
out = readability >= 4.5;
|
|
1258
|
+
break;
|
|
1259
|
+
case 'AAlarge':
|
|
1260
|
+
out = readability >= 3;
|
|
1261
|
+
break;
|
|
1262
|
+
case 'AAAsmall':
|
|
1263
|
+
out = readability >= 7;
|
|
1264
|
+
break;
|
|
1265
|
+
}
|
|
1266
|
+
return out;
|
|
1267
|
+
}
|
|
1268
|
+
static mostReadable(baseColor, colorList, args) {
|
|
1269
|
+
let bestColor = '';
|
|
1270
|
+
let bestScore = 0;
|
|
1271
|
+
let readability;
|
|
1272
|
+
let includeFallbackColors, level, size;
|
|
1273
|
+
args = args || {};
|
|
1274
|
+
includeFallbackColors = args.includeFallbackColors;
|
|
1275
|
+
level = args.level;
|
|
1276
|
+
size = args.size;
|
|
1277
|
+
for (let item of colorList) {
|
|
1278
|
+
readability = TinyColor.readability(baseColor, item);
|
|
1279
|
+
if (readability > bestScore) {
|
|
1280
|
+
bestScore = readability;
|
|
1281
|
+
bestColor = new TinyColor(item);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
if (TinyColor.isReadable(baseColor, bestColor, {
|
|
1285
|
+
level: level,
|
|
1286
|
+
size: size,
|
|
1287
|
+
}) ||
|
|
1288
|
+
!includeFallbackColors) {
|
|
1289
|
+
return bestColor;
|
|
1290
|
+
}
|
|
1291
|
+
else {
|
|
1292
|
+
args.includeFallbackColors = false;
|
|
1293
|
+
return TinyColor.mostReadable(baseColor, ['#fff', '#000'], args);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
clamp01(val) {
|
|
1297
|
+
return mathMin(1, mathMax(0, val));
|
|
1298
|
+
}
|
|
1299
|
+
_flip() {
|
|
1300
|
+
let flipped = {};
|
|
1301
|
+
let allName = TinyColor.initNames();
|
|
1302
|
+
for (let i in allName) {
|
|
1303
|
+
if (allName.hasOwnProperty(i)) {
|
|
1304
|
+
flipped[allName[i]] = i;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
return flipped;
|
|
1308
|
+
}
|
|
1309
|
+
isValidCSSUnit(color) {
|
|
1310
|
+
return !!this.matchers.CSS_UNIT.exec(color);
|
|
1311
|
+
}
|
|
1312
|
+
isOnePointZero(n) {
|
|
1313
|
+
return typeof n == 'string' && n.indexOf('.') != -1 && parseFloat(n) === 1;
|
|
1314
|
+
}
|
|
1315
|
+
isPercentage(n) {
|
|
1316
|
+
return typeof n === 'string' && n.indexOf('%') != -1;
|
|
1317
|
+
}
|
|
1318
|
+
pad2(c) {
|
|
1319
|
+
return c.length == 1 ? '0' + c : '' + c;
|
|
1320
|
+
}
|
|
1321
|
+
bound01(n, max) {
|
|
1322
|
+
if (this.isOnePointZero(n)) {
|
|
1323
|
+
n = '100%';
|
|
1324
|
+
}
|
|
1325
|
+
let processPercent = this.isPercentage(n);
|
|
1326
|
+
n = mathMin(max, mathMax(0, parseFloat(n)));
|
|
1327
|
+
// Automatically convert percentage into number
|
|
1328
|
+
if (processPercent) {
|
|
1329
|
+
n = parseInt('' + n * max, 10) / 100;
|
|
1330
|
+
}
|
|
1331
|
+
// Handle floating point rounding errors
|
|
1332
|
+
if (Math.abs(n - max) < 0.000001) {
|
|
1333
|
+
return 1;
|
|
1334
|
+
}
|
|
1335
|
+
// Convert into [0, 1] range if it isn't already
|
|
1336
|
+
return (n % max) / parseFloat(max);
|
|
1337
|
+
}
|
|
1338
|
+
convertDecimalToHex(d) {
|
|
1339
|
+
return Math.round(parseFloat(d) * 255).toString(16);
|
|
1340
|
+
}
|
|
1341
|
+
rgbToRgb(r, g, b) {
|
|
1342
|
+
return {
|
|
1343
|
+
r: this.bound01(r, 255) * 255,
|
|
1344
|
+
g: this.bound01(g, 255) * 255,
|
|
1345
|
+
b: this.bound01(b, 255) * 255,
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1348
|
+
hsvToRgb(h, s, v) {
|
|
1349
|
+
h = this.bound01(h, 360) * 6;
|
|
1350
|
+
s = this.bound01(s, 100);
|
|
1351
|
+
v = this.bound01(v, 100);
|
|
1352
|
+
let i = Math.floor(h), f = h - i, p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s), mod = i % 6, r = [v, q, p, p, t, v][mod], g = [t, v, v, q, p, p][mod], b = [p, p, t, v, v, q][mod];
|
|
1353
|
+
return { r: r * 255, g: g * 255, b: b * 255 };
|
|
1354
|
+
}
|
|
1355
|
+
hslToRgb(h, s, l) {
|
|
1356
|
+
let r, g, b;
|
|
1357
|
+
h = this.bound01(h, 360);
|
|
1358
|
+
s = this.bound01(s, 100);
|
|
1359
|
+
l = this.bound01(l, 100);
|
|
1360
|
+
function hue2rgb(p, q, t) {
|
|
1361
|
+
if (t < 0)
|
|
1362
|
+
t += 1;
|
|
1363
|
+
if (t > 1)
|
|
1364
|
+
t -= 1;
|
|
1365
|
+
if (t < 1 / 6)
|
|
1366
|
+
return p + (q - p) * 6 * t;
|
|
1367
|
+
if (t < 1 / 2)
|
|
1368
|
+
return q;
|
|
1369
|
+
if (t < 2 / 3)
|
|
1370
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
1371
|
+
return p;
|
|
1372
|
+
}
|
|
1373
|
+
if (s === 0) {
|
|
1374
|
+
r = g = b = l; // achromatic
|
|
1375
|
+
}
|
|
1376
|
+
else {
|
|
1377
|
+
let q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
1378
|
+
let p = 2 * l - q;
|
|
1379
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
1380
|
+
g = hue2rgb(p, q, h);
|
|
1381
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
1382
|
+
}
|
|
1383
|
+
return { r: r * 255, g: g * 255, b: b * 255 };
|
|
1384
|
+
}
|
|
1385
|
+
rgbToHsl(r, g, b) {
|
|
1386
|
+
r = this.bound01(r, 255);
|
|
1387
|
+
g = this.bound01(g, 255);
|
|
1388
|
+
b = this.bound01(b, 255);
|
|
1389
|
+
let max = mathMax(r, g, b), min = mathMin(r, g, b);
|
|
1390
|
+
let h, s, l = (max + min) / 2;
|
|
1391
|
+
if (max == min) {
|
|
1392
|
+
h = s = 0; // achromatic
|
|
1393
|
+
}
|
|
1394
|
+
else {
|
|
1395
|
+
let d = max - min;
|
|
1396
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
1397
|
+
switch (max) {
|
|
1398
|
+
case r:
|
|
1399
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
1400
|
+
break;
|
|
1401
|
+
case g:
|
|
1402
|
+
h = (b - r) / d + 2;
|
|
1403
|
+
break;
|
|
1404
|
+
case b:
|
|
1405
|
+
h = (r - g) / d + 4;
|
|
1406
|
+
break;
|
|
1407
|
+
}
|
|
1408
|
+
h /= 6;
|
|
1409
|
+
}
|
|
1410
|
+
return { h: h, s: s, l: l };
|
|
1411
|
+
}
|
|
1412
|
+
rgbToHsv(r, g, b) {
|
|
1413
|
+
r = this.bound01(r, 255);
|
|
1414
|
+
g = this.bound01(g, 255);
|
|
1415
|
+
b = this.bound01(b, 255);
|
|
1416
|
+
let max = mathMax(r, g, b), min = mathMin(r, g, b);
|
|
1417
|
+
let h, s, v = max;
|
|
1418
|
+
let d = max - min;
|
|
1419
|
+
s = max === 0 ? 0 : d / max;
|
|
1420
|
+
if (max == min) {
|
|
1421
|
+
h = 0; // achromatic
|
|
1422
|
+
}
|
|
1423
|
+
else {
|
|
1424
|
+
switch (max) {
|
|
1425
|
+
case r:
|
|
1426
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
1427
|
+
break;
|
|
1428
|
+
case g:
|
|
1429
|
+
h = (b - r) / d + 2;
|
|
1430
|
+
break;
|
|
1431
|
+
case b:
|
|
1432
|
+
h = (r - g) / d + 4;
|
|
1433
|
+
break;
|
|
1434
|
+
}
|
|
1435
|
+
h /= 6;
|
|
1436
|
+
}
|
|
1437
|
+
return { h: h, s: s, v: v };
|
|
1438
|
+
}
|
|
1439
|
+
rgbToHex(r, g, b, allow3Char) {
|
|
1440
|
+
let hex = [this.pad2(mathRound(r).toString(16)), this.pad2(mathRound(g).toString(16)), this.pad2(mathRound(b).toString(16))];
|
|
1441
|
+
// Return a 3 character hex if possible
|
|
1442
|
+
if (allow3Char &&
|
|
1443
|
+
hex[0].charAt(0) == hex[0].charAt(1) &&
|
|
1444
|
+
hex[1].charAt(0) == hex[1].charAt(1) &&
|
|
1445
|
+
hex[2].charAt(0) == hex[2].charAt(1)) {
|
|
1446
|
+
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
|
|
1447
|
+
}
|
|
1448
|
+
return hex.join('');
|
|
1449
|
+
}
|
|
1450
|
+
rgbaToHex(r, g, b, a, allow4Char) {
|
|
1451
|
+
let hex = [
|
|
1452
|
+
this.pad2(mathRound(r).toString(16)),
|
|
1453
|
+
this.pad2(mathRound(g).toString(16)),
|
|
1454
|
+
this.pad2(mathRound(b).toString(16)),
|
|
1455
|
+
this.pad2(this.convertDecimalToHex('' + a)),
|
|
1456
|
+
];
|
|
1457
|
+
// Return a 4 character hex if possible
|
|
1458
|
+
if (allow4Char &&
|
|
1459
|
+
hex[0].charAt(0) == hex[0].charAt(1) &&
|
|
1460
|
+
hex[1].charAt(0) == hex[1].charAt(1) &&
|
|
1461
|
+
hex[2].charAt(0) == hex[2].charAt(1) &&
|
|
1462
|
+
hex[3].charAt(0) == hex[3].charAt(1)) {
|
|
1463
|
+
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
|
|
1464
|
+
}
|
|
1465
|
+
return hex.join('');
|
|
1466
|
+
}
|
|
1467
|
+
rgbaToArgbHex(r, g, b, a) {
|
|
1468
|
+
let hex = [
|
|
1469
|
+
this.pad2(this.convertDecimalToHex('' + a)),
|
|
1470
|
+
this.pad2(mathRound(r).toString(16)),
|
|
1471
|
+
this.pad2(mathRound(g).toString(16)),
|
|
1472
|
+
this.pad2(mathRound(b).toString(16)),
|
|
1473
|
+
];
|
|
1474
|
+
return hex.join('');
|
|
1475
|
+
}
|
|
1476
|
+
static convertToPercentage(n) {
|
|
1477
|
+
if (n <= 1) {
|
|
1478
|
+
n = n * 100 + '%';
|
|
1479
|
+
}
|
|
1480
|
+
return n;
|
|
1481
|
+
}
|
|
1482
|
+
boundAlpha(a) {
|
|
1483
|
+
a = parseFloat(a);
|
|
1484
|
+
if (isNaN(a) || a < 0 || a > 1) {
|
|
1485
|
+
a = 1;
|
|
1486
|
+
}
|
|
1487
|
+
return a;
|
|
1488
|
+
}
|
|
1489
|
+
inputToRGB(color) {
|
|
1490
|
+
let rgb = { r: 0, g: 0, b: 0 };
|
|
1491
|
+
let a = 1;
|
|
1492
|
+
let s = null;
|
|
1493
|
+
let v = null;
|
|
1494
|
+
let l = null;
|
|
1495
|
+
let ok = false;
|
|
1496
|
+
let format = '';
|
|
1497
|
+
if (color === null) {
|
|
1498
|
+
color = '';
|
|
1499
|
+
}
|
|
1500
|
+
if (typeof color == 'string') {
|
|
1501
|
+
color = this.stringInputToObject(color);
|
|
1502
|
+
}
|
|
1503
|
+
if (typeof color == 'object') {
|
|
1504
|
+
if (this.isValidCSSUnit(color.r) && this.isValidCSSUnit(color.g) && this.isValidCSSUnit(color.b)) {
|
|
1505
|
+
rgb = this.rgbToRgb(color.r, color.g, color.b);
|
|
1506
|
+
ok = true;
|
|
1507
|
+
format = String(color.r).substr(-1) === '%' ? 'prgb' : 'rgb';
|
|
1508
|
+
}
|
|
1509
|
+
else if (this.isValidCSSUnit(color.h) && this.isValidCSSUnit(color.s) && this.isValidCSSUnit(color.v)) {
|
|
1510
|
+
s = TinyColor.convertToPercentage(color.s);
|
|
1511
|
+
v = TinyColor.convertToPercentage(color.v);
|
|
1512
|
+
rgb = this.hsvToRgb(color.h, s, v);
|
|
1513
|
+
ok = true;
|
|
1514
|
+
format = 'hsv';
|
|
1515
|
+
}
|
|
1516
|
+
else if (this.isValidCSSUnit(color.h) && this.isValidCSSUnit(color.s) && this.isValidCSSUnit(color.l)) {
|
|
1517
|
+
s = TinyColor.convertToPercentage(color.s);
|
|
1518
|
+
l = TinyColor.convertToPercentage(color.l);
|
|
1519
|
+
rgb = this.hslToRgb(color.h, s, l);
|
|
1520
|
+
ok = true;
|
|
1521
|
+
format = 'hsl';
|
|
1522
|
+
}
|
|
1523
|
+
if (color.hasOwnProperty('a')) {
|
|
1524
|
+
a = color.a;
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
a = this.boundAlpha(a);
|
|
1528
|
+
return {
|
|
1529
|
+
ok: ok,
|
|
1530
|
+
format: color.format || format,
|
|
1531
|
+
r: mathMin(255, mathMax(rgb.r, 0)),
|
|
1532
|
+
g: mathMin(255, mathMax(rgb.g, 0)),
|
|
1533
|
+
b: mathMin(255, mathMax(rgb.b, 0)),
|
|
1534
|
+
a: a,
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
parseIntFromHex(val) {
|
|
1538
|
+
return parseInt(val, 16);
|
|
1539
|
+
}
|
|
1540
|
+
convertHexToDecimal(h) {
|
|
1541
|
+
return this.parseIntFromHex(h) / 255;
|
|
1542
|
+
}
|
|
1543
|
+
stringInputToObject(color) {
|
|
1544
|
+
color = color.replace(trimLeft, '').replace(trimRight, '').toLowerCase();
|
|
1545
|
+
let named = false;
|
|
1546
|
+
if (this.names[color]) {
|
|
1547
|
+
color = this.names[color];
|
|
1548
|
+
named = true;
|
|
1549
|
+
}
|
|
1550
|
+
else if (color == 'transparent') {
|
|
1551
|
+
return { r: 0, g: 0, b: 0, a: 0, format: 'name' };
|
|
1552
|
+
}
|
|
1553
|
+
// Try to match string input using regular expressions.
|
|
1554
|
+
// Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
|
|
1555
|
+
// Just return an object and let the conversion functions handle that.
|
|
1556
|
+
// This way the result will be the same whether the tinycolor is initialized with string or object.
|
|
1557
|
+
let match;
|
|
1558
|
+
if ((match = this.matchers.rgb.exec(color))) {
|
|
1559
|
+
return { r: match[1], g: match[2], b: match[3] };
|
|
1560
|
+
}
|
|
1561
|
+
if ((match = this.matchers.rgba.exec(color))) {
|
|
1562
|
+
return { r: match[1], g: match[2], b: match[3], a: match[4] };
|
|
1563
|
+
}
|
|
1564
|
+
if ((match = this.matchers.hsl.exec(color))) {
|
|
1565
|
+
return { h: match[1], s: match[2], l: match[3] };
|
|
1566
|
+
}
|
|
1567
|
+
if ((match = this.matchers.hsla.exec(color))) {
|
|
1568
|
+
return { h: match[1], s: match[2], l: match[3], a: match[4] };
|
|
1569
|
+
}
|
|
1570
|
+
if ((match = this.matchers.hsv.exec(color))) {
|
|
1571
|
+
return { h: match[1], s: match[2], v: match[3] };
|
|
1572
|
+
}
|
|
1573
|
+
if ((match = this.matchers.hsva.exec(color))) {
|
|
1574
|
+
return { h: match[1], s: match[2], v: match[3], a: match[4] };
|
|
1575
|
+
}
|
|
1576
|
+
if ((match = this.matchers.hex8.exec(color))) {
|
|
1577
|
+
return {
|
|
1578
|
+
r: this.parseIntFromHex(match[1]),
|
|
1579
|
+
g: this.parseIntFromHex(match[2]),
|
|
1580
|
+
b: this.parseIntFromHex(match[3]),
|
|
1581
|
+
a: this.convertHexToDecimal(match[4]),
|
|
1582
|
+
format: named ? 'name' : 'hex8',
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
1585
|
+
if ((match = this.matchers.hex6.exec(color))) {
|
|
1586
|
+
return {
|
|
1587
|
+
r: this.parseIntFromHex(match[1]),
|
|
1588
|
+
g: this.parseIntFromHex(match[2]),
|
|
1589
|
+
b: this.parseIntFromHex(match[3]),
|
|
1590
|
+
format: named ? 'name' : 'hex',
|
|
1591
|
+
};
|
|
1592
|
+
}
|
|
1593
|
+
if ((match = this.matchers.hex4.exec(color))) {
|
|
1594
|
+
return {
|
|
1595
|
+
r: this.parseIntFromHex(match[1] + '' + match[1]),
|
|
1596
|
+
g: this.parseIntFromHex(match[2] + '' + match[2]),
|
|
1597
|
+
b: this.parseIntFromHex(match[3] + '' + match[3]),
|
|
1598
|
+
a: this.convertHexToDecimal(match[4] + '' + match[4]),
|
|
1599
|
+
format: named ? 'name' : 'hex8',
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1602
|
+
if ((match = this.matchers.hex3.exec(color))) {
|
|
1603
|
+
return {
|
|
1604
|
+
r: this.parseIntFromHex(match[1] + '' + match[1]),
|
|
1605
|
+
g: this.parseIntFromHex(match[2] + '' + match[2]),
|
|
1606
|
+
b: this.parseIntFromHex(match[3] + '' + match[3]),
|
|
1607
|
+
format: named ? 'name' : 'hex',
|
|
1608
|
+
};
|
|
1609
|
+
}
|
|
1610
|
+
return false;
|
|
1611
|
+
}
|
|
1612
|
+
static validateWCAG2Parms(parms) {
|
|
1613
|
+
// return valid WCAG2 parms for isReadable.
|
|
1614
|
+
// If input parms are invalid, return {"level":"AA", "size":"small"}
|
|
1615
|
+
let level, size;
|
|
1616
|
+
parms = parms || { level: 'AA', size: 'small' };
|
|
1617
|
+
level = (parms.level || 'AA').toUpperCase();
|
|
1618
|
+
size = (parms.size || 'small').toLowerCase();
|
|
1619
|
+
if (level !== 'AA' && level !== 'AAA') {
|
|
1620
|
+
level = 'AA';
|
|
1621
|
+
}
|
|
1622
|
+
if (size !== 'small' && size !== 'large') {
|
|
1623
|
+
size = 'small';
|
|
1624
|
+
}
|
|
1625
|
+
return { level: level, size: size };
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
function defineStore(storeFunction) {
|
|
1630
|
+
/**
|
|
1631
|
+
* 初始化数据
|
|
1632
|
+
*
|
|
1633
|
+
*/
|
|
1634
|
+
// 获取store
|
|
1635
|
+
const store = storeFunction();
|
|
1636
|
+
// 备份初始store
|
|
1637
|
+
const storeBackups = {};
|
|
1638
|
+
const storeKeys = Object.keys(store).filter(key => isRef(store[key]) || isReactive(store[key]));
|
|
1639
|
+
storeKeys.forEach(key => (storeBackups[key] = cloneDeep(isRef(store[key]) ? unref(store[key]) : toRaw(store[key]))));
|
|
1640
|
+
// 初始化store
|
|
1641
|
+
const storeInit = () => {
|
|
1642
|
+
storeKeys.forEach((key) => {
|
|
1643
|
+
if (isRef(store[key])) {
|
|
1644
|
+
store[key].value = cloneDeep(storeBackups[key]);
|
|
1645
|
+
}
|
|
1646
|
+
else if (isReactive(store[key])) {
|
|
1647
|
+
Object.keys(store[key]).forEach(reactiveKey => delete store[key][reactiveKey]);
|
|
1648
|
+
Object.assign(store[key], cloneDeep(storeBackups[key]));
|
|
1649
|
+
}
|
|
1650
|
+
});
|
|
1651
|
+
};
|
|
1652
|
+
/**
|
|
1653
|
+
* 活动Components
|
|
1654
|
+
*
|
|
1655
|
+
*/
|
|
1656
|
+
let componentsCount = 0;
|
|
1657
|
+
const countPlus = () => {
|
|
1658
|
+
componentsCount++;
|
|
1659
|
+
};
|
|
1660
|
+
const countMinus = () => {
|
|
1661
|
+
componentsCount--;
|
|
1662
|
+
componentsCount === 0 && storeInit();
|
|
1663
|
+
};
|
|
1664
|
+
/**
|
|
1665
|
+
* 组件内调用
|
|
1666
|
+
*/
|
|
1667
|
+
return (component) => {
|
|
1668
|
+
// 组件自定义周期
|
|
1669
|
+
if (component) {
|
|
1670
|
+
onMounted(() => component.value.setStore(countPlus, countMinus));
|
|
1671
|
+
}
|
|
1672
|
+
// 根据组件周期自动销毁数据
|
|
1673
|
+
else {
|
|
1674
|
+
onMounted(countPlus);
|
|
1675
|
+
// 使用宏任务,让组件切换时不执行init
|
|
1676
|
+
onUnmounted(() => setTimeout(countMinus));
|
|
1677
|
+
}
|
|
1678
|
+
return store;
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
/*
|
|
1683
|
+
* @Description: 发布订阅(需要有生命周期)
|
|
1684
|
+
* @Author: Zye
|
|
1685
|
+
* @Date: 2022-12-08
|
|
1686
|
+
*/
|
|
1687
|
+
function Subscribe() {
|
|
1688
|
+
// 存放订阅者
|
|
1689
|
+
const callbacks = [];
|
|
1690
|
+
// 设置订阅者
|
|
1691
|
+
const setCallback = (callback) => {
|
|
1692
|
+
if (callbacks.includes(callback))
|
|
1693
|
+
return;
|
|
1694
|
+
callbacks.push(callback);
|
|
1695
|
+
};
|
|
1696
|
+
// 移除订阅者
|
|
1697
|
+
const removeCallBack = (callback) => {
|
|
1698
|
+
const index = callbacks.indexOf(callback);
|
|
1699
|
+
index > -1 && callbacks.splice(index, 1);
|
|
1700
|
+
};
|
|
1701
|
+
return {
|
|
1702
|
+
send(...args) {
|
|
1703
|
+
callbacks.forEach((callback) => callback(...args));
|
|
1704
|
+
},
|
|
1705
|
+
set onmessage(callback) {
|
|
1706
|
+
if (onMounted) {
|
|
1707
|
+
onMounted(() => setCallback(callback));
|
|
1708
|
+
onUnmounted(() => removeCallBack(callback));
|
|
1709
|
+
}
|
|
1710
|
+
else {
|
|
1711
|
+
console.error(`subscribe当前所处位置无生命周期,callback无法被订阅\n${callback}`);
|
|
1712
|
+
}
|
|
1713
|
+
},
|
|
1714
|
+
};
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
/**
|
|
1718
|
+
*
|
|
1719
|
+
* @param callback 回调函数
|
|
1720
|
+
* @param throttleTime 节流时长
|
|
1721
|
+
*
|
|
1722
|
+
*
|
|
1723
|
+
* @example
|
|
1724
|
+
*
|
|
1725
|
+
* 1. 初始化 api/dict.ts -> initDict
|
|
1726
|
+
*
|
|
1727
|
+
* // initDict 接收callback函数,callback函数的参数为字典类型集合,如['dictType1','dictType2']
|
|
1728
|
+
* // initDict 返回值为字典集合,如{dictType1:[],dictType2:[]},可以为异步
|
|
1729
|
+
* export const useDict = initDict((dictTypes:string[])=>{
|
|
1730
|
+
* return http.get('/api/dict'{dictTypes})
|
|
1731
|
+
* })
|
|
1732
|
+
*
|
|
1733
|
+
* 2. 注册 views/xxx/xxx.vue -> useDict
|
|
1734
|
+
*
|
|
1735
|
+
* //页面注册dict ( 用于保存页面dict数据 )
|
|
1736
|
+
* const dict = useDict()
|
|
1737
|
+
*
|
|
1738
|
+
* 3. 调用 views/xxx/xxx.vue -> dict
|
|
1739
|
+
* dict('dictType1') // 获取dictType1字典
|
|
1740
|
+
* dict('dictType2') // 获取dictType2字典
|
|
1741
|
+
*
|
|
1742
|
+
* @returns
|
|
1743
|
+
*/
|
|
1744
|
+
const initDict = (callback, throttleTime = 100) => {
|
|
1745
|
+
const useDict = () => {
|
|
1746
|
+
const dictTypes = [];
|
|
1747
|
+
const dictArrs = {};
|
|
1748
|
+
const dict = throttle(async (cb, dictType) => {
|
|
1749
|
+
const setDictTypes = [...new Set(dictTypes)];
|
|
1750
|
+
const res = await callback(setDictTypes);
|
|
1751
|
+
setDictTypes.forEach((dictType) => {
|
|
1752
|
+
!dictArrs[dictType].value?.length && dictArrs[dictType].value.push(...res[dictType]);
|
|
1753
|
+
});
|
|
1754
|
+
cb?.(res[dictType]);
|
|
1755
|
+
}, throttleTime, { leading: false });
|
|
1756
|
+
const getDict = (dictType, cb) => {
|
|
1757
|
+
if (!dictArrs[dictType]) {
|
|
1758
|
+
dictArrs[dictType] = ref([]);
|
|
1759
|
+
dictTypes.push(dictType);
|
|
1760
|
+
dict(cb, dictType);
|
|
1761
|
+
}
|
|
1762
|
+
return dictArrs[dictType].value;
|
|
1763
|
+
};
|
|
1764
|
+
return getDict;
|
|
1765
|
+
};
|
|
1766
|
+
return useDict;
|
|
1767
|
+
};
|
|
1768
|
+
|
|
1769
|
+
/**
|
|
1770
|
+
*
|
|
1771
|
+
* 将文件夹下的文件按照 {文件名:文件} 的格式返回对象
|
|
1772
|
+
*
|
|
1773
|
+
* @param files
|
|
1774
|
+
* @param stop
|
|
1775
|
+
* @returns
|
|
1776
|
+
*/
|
|
1777
|
+
function importFile(files, stop) {
|
|
1778
|
+
const fileObj = {};
|
|
1779
|
+
Object.keys(files).forEach((key) => {
|
|
1780
|
+
if (stop?.(key))
|
|
1781
|
+
return;
|
|
1782
|
+
const path = key.match(/\/([\w0-9\-]+)\/([\w0-9\-]+)\./);
|
|
1783
|
+
if (path)
|
|
1784
|
+
fileObj[path[2] === 'index' ? path[1] : path[2]] = files[key];
|
|
1785
|
+
});
|
|
1786
|
+
return fileObj;
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
*
|
|
1790
|
+
* 获取文件上传状态
|
|
1791
|
+
*
|
|
1792
|
+
* @returns 文件被拖入浏览器ref(true) 文件被拖出浏览器/松开鼠标(false)
|
|
1793
|
+
*/
|
|
1794
|
+
function dragEvent() {
|
|
1795
|
+
const drag = ref(false);
|
|
1796
|
+
const _true = () => (drag.value = true);
|
|
1797
|
+
const _false = () => (drag.value = false);
|
|
1798
|
+
const _in = throttle(_true, 200);
|
|
1799
|
+
const _out = debounce(_false, 200);
|
|
1800
|
+
const _over = (e) => {
|
|
1801
|
+
e.preventDefault();
|
|
1802
|
+
_in();
|
|
1803
|
+
_out();
|
|
1804
|
+
};
|
|
1805
|
+
onMounted(() => {
|
|
1806
|
+
document.addEventListener('dragover', _over, false);
|
|
1807
|
+
document.addEventListener('drop', _false, false);
|
|
1808
|
+
});
|
|
1809
|
+
onUnmounted(() => {
|
|
1810
|
+
document.removeEventListener('dragover', _over);
|
|
1811
|
+
document.removeEventListener('drop', _false);
|
|
1812
|
+
});
|
|
1813
|
+
return drag;
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
export { Num, Subscribe, TinyColor, addPx, assignObject, browserEngine, createHttp, defineStore, dragEvent, exitFullscreen, expose, fullscreen, getDate, getObject, getSpecialDate, getTime, importFile, inFullscreen, initDict, isFullscreen, isUrl, on, pathToHump, query, setTime, setValue, toHump, toHyphen, urlToData };
|