sculp-js 1.5.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/array.js +2 -21
- package/lib/cjs/async.js +2 -2
- package/lib/cjs/base64.js +62 -0
- package/lib/cjs/clipboard.js +2 -2
- package/lib/cjs/cookie.js +2 -2
- package/lib/cjs/date.js +2 -3
- package/lib/cjs/dom.js +2 -2
- package/lib/cjs/download.js +4 -4
- package/lib/cjs/easing.js +2 -2
- package/lib/cjs/file.js +2 -2
- package/lib/cjs/func.js +3 -3
- package/lib/cjs/index.js +15 -5
- package/lib/cjs/math.js +88 -0
- package/lib/cjs/number.js +2 -2
- package/lib/cjs/object.js +10 -20
- package/lib/cjs/path.js +2 -2
- package/lib/cjs/qs.js +2 -2
- package/lib/cjs/random.js +2 -2
- package/lib/cjs/string.js +2 -2
- package/lib/cjs/tooltip.js +2 -2
- package/lib/cjs/tree.js +2 -2
- package/lib/cjs/type.js +68 -2
- package/lib/cjs/unique.js +2 -2
- package/lib/cjs/url.js +2 -2
- package/lib/cjs/watermark.js +2 -2
- package/lib/cjs/we-decode.js +2 -2
- package/lib/es/array.js +3 -21
- package/lib/es/async.js +2 -2
- package/lib/es/base64.js +59 -0
- package/lib/es/clipboard.js +2 -2
- package/lib/es/cookie.js +2 -2
- package/lib/es/date.js +2 -3
- package/lib/es/dom.js +2 -2
- package/lib/es/download.js +4 -4
- package/lib/es/easing.js +2 -2
- package/lib/es/file.js +2 -2
- package/lib/es/func.js +3 -3
- package/lib/es/index.js +8 -6
- package/lib/es/math.js +82 -0
- package/lib/es/number.js +2 -2
- package/lib/es/object.js +9 -18
- package/lib/es/path.js +2 -2
- package/lib/es/qs.js +2 -2
- package/lib/es/random.js +2 -2
- package/lib/es/string.js +2 -2
- package/lib/es/tooltip.js +2 -2
- package/lib/es/tree.js +2 -2
- package/lib/es/type.js +66 -3
- package/lib/es/unique.js +2 -2
- package/lib/es/url.js +2 -2
- package/lib/es/watermark.js +2 -2
- package/lib/es/we-decode.js +2 -2
- package/lib/index.d.ts +93 -16
- package/lib/umd/index.js +320 -151
- package/package.json +2 -2
package/lib/umd/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
3
|
-
* (c) 2023-
|
|
2
|
+
* sculp-js v1.6.1
|
|
3
|
+
* (c) 2023-2025 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -10,6 +10,117 @@
|
|
|
10
10
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.sculpJs = {}, global.bezier));
|
|
11
11
|
})(this, (function (exports, bezier) { 'use strict';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* 遍历数组,返回 false 中断遍历(支持continue和break操作)
|
|
15
|
+
*
|
|
16
|
+
* @param {ArrayLike<V>} array
|
|
17
|
+
* @param {(val: V, idx: number) => any} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
|
|
18
|
+
* @param {boolean} reverse 是否倒序
|
|
19
|
+
* @returns {*}
|
|
20
|
+
*/
|
|
21
|
+
function arrayEach(array, iterator, reverse = false) {
|
|
22
|
+
if (reverse) {
|
|
23
|
+
for (let idx = array.length - 1; idx >= 0; idx--) {
|
|
24
|
+
const val = array[idx];
|
|
25
|
+
const re = iterator(val, idx, array);
|
|
26
|
+
if (re === false)
|
|
27
|
+
break;
|
|
28
|
+
else if (re === true)
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
for (let idx = 0; idx < array.length; idx++) {
|
|
34
|
+
const val = array[idx];
|
|
35
|
+
const re = iterator(val, idx, array);
|
|
36
|
+
if (re === false)
|
|
37
|
+
break;
|
|
38
|
+
else if (re === true)
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 异步遍历数组,返回 false 中断遍历
|
|
45
|
+
* @param {ArrayLike<V>} array 数组
|
|
46
|
+
* @param {(val: V, idx: number) => Promise<any>} iterator 支持Promise类型的回调函数
|
|
47
|
+
* @param {boolean} reverse 是否反向遍历
|
|
48
|
+
*/
|
|
49
|
+
async function arrayEachAsync(array, iterator, reverse = false) {
|
|
50
|
+
if (reverse) {
|
|
51
|
+
for (let idx = array.length - 1; idx >= 0; idx--) {
|
|
52
|
+
const val = array[idx];
|
|
53
|
+
if ((await iterator(val, idx)) === false)
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
for (let idx = 0; idx < array.length; idx++) {
|
|
59
|
+
const val = array[idx];
|
|
60
|
+
if ((await iterator(val, idx)) === false)
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 插入到目标位置之前
|
|
67
|
+
* @param {AnyArray} array
|
|
68
|
+
* @param {number} start
|
|
69
|
+
* @param {number} to
|
|
70
|
+
* @returns {*}
|
|
71
|
+
*/
|
|
72
|
+
function arrayInsertBefore(array, start, to) {
|
|
73
|
+
if (start === to || start + 1 === to)
|
|
74
|
+
return;
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
76
|
+
const [source] = array.splice(start, 1);
|
|
77
|
+
const insertIndex = to < start ? to : to - 1;
|
|
78
|
+
array.splice(insertIndex, 0, source);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 数组删除指定项目
|
|
82
|
+
* @param {V[]} array
|
|
83
|
+
* @param {(val: V, idx: number) => boolean} expect
|
|
84
|
+
* @returns {V[]}
|
|
85
|
+
*/
|
|
86
|
+
function arrayRemove(array, expect) {
|
|
87
|
+
const indexes = [];
|
|
88
|
+
// 这里重命名一下:是为了杜绝 jest 里的 expect 与之产生检查错误
|
|
89
|
+
// eslint 的 jest 语法检查是遇到 expect 函数就以为是单元测试
|
|
90
|
+
const _expect = expect;
|
|
91
|
+
arrayEach(array, (val, idx) => {
|
|
92
|
+
if (_expect(val, idx))
|
|
93
|
+
indexes.push(idx);
|
|
94
|
+
});
|
|
95
|
+
indexes.forEach((val, idx) => array.splice(val - idx, 1));
|
|
96
|
+
return array;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 常用类型定义
|
|
100
|
+
/**
|
|
101
|
+
* 判断对象内是否有该静态属性
|
|
102
|
+
* @param {object} obj
|
|
103
|
+
* @param {string} key
|
|
104
|
+
* @returns {boolean}
|
|
105
|
+
*/
|
|
106
|
+
function objectHas(obj, key) {
|
|
107
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* 判断一个对象是否为类数组
|
|
111
|
+
*
|
|
112
|
+
* @param any
|
|
113
|
+
* @returns {boolean}
|
|
114
|
+
*/
|
|
115
|
+
function arrayLike(any) {
|
|
116
|
+
if (isArray(any))
|
|
117
|
+
return true;
|
|
118
|
+
if (isString(any))
|
|
119
|
+
return true;
|
|
120
|
+
if (!isObject(any))
|
|
121
|
+
return false;
|
|
122
|
+
return objectHas(any, 'length');
|
|
123
|
+
}
|
|
13
124
|
/**
|
|
14
125
|
* 判断任意值的数据类型
|
|
15
126
|
* @param {unknown} any
|
|
@@ -56,6 +167,72 @@
|
|
|
56
167
|
return false;
|
|
57
168
|
}
|
|
58
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Checks if `value` is an empty object, collection, map, or set.
|
|
172
|
+
*
|
|
173
|
+
* Objects are considered empty if they have no own enumerable string keyed
|
|
174
|
+
* properties.
|
|
175
|
+
*
|
|
176
|
+
* Array-like values such as `arguments` objects, arrays, buffers, strings, or
|
|
177
|
+
* jQuery-like collections are considered empty if they have a `length` of `0`.
|
|
178
|
+
* Similarly, maps and sets are considered empty if they have a `size` of `0`.
|
|
179
|
+
*
|
|
180
|
+
* @param {*} value The value to check.
|
|
181
|
+
* @returns {boolean} Returns `true` if `value` is empty, else `false`.
|
|
182
|
+
* @example
|
|
183
|
+
*
|
|
184
|
+
* _.isEmpty(null);
|
|
185
|
+
* // => true
|
|
186
|
+
*
|
|
187
|
+
* _.isEmpty(true);
|
|
188
|
+
* // => true
|
|
189
|
+
*
|
|
190
|
+
* _.isEmpty(1);
|
|
191
|
+
* // => true
|
|
192
|
+
*
|
|
193
|
+
* _.isEmpty([1, 2, 3]);
|
|
194
|
+
* // => false
|
|
195
|
+
*
|
|
196
|
+
* _.isEmpty({ 'a': 1 });
|
|
197
|
+
* // => false
|
|
198
|
+
*/
|
|
199
|
+
function isEmpty(value) {
|
|
200
|
+
if (isNullOrUnDef(value) || Number.isNaN(value)) {
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
if (arrayLike(value) && (isArray(value) || isString(value) || isFunction(value.splice))) {
|
|
204
|
+
return !value.length;
|
|
205
|
+
}
|
|
206
|
+
return !Object.keys(value).length;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// @ref https://cubic-bezier.com/
|
|
210
|
+
const easingDefines = {
|
|
211
|
+
linear: [0, 0, 1, 1],
|
|
212
|
+
ease: [0.25, 0.1, 0.25, 1],
|
|
213
|
+
'ease-in': [0.42, 0, 1, 1],
|
|
214
|
+
'ease-out': [0, 0, 0.58, 1],
|
|
215
|
+
'ease-in-out': [0.42, 0, 0.58, 1]
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* 缓冲函数化,用于 js 计算缓冲进度
|
|
219
|
+
* @param {EasingNameOrDefine} [name=linear]
|
|
220
|
+
* @returns {EasingFunction}
|
|
221
|
+
*/
|
|
222
|
+
function easingFunctional(name) {
|
|
223
|
+
let fn;
|
|
224
|
+
if (isArray(name)) {
|
|
225
|
+
fn = bezier(...name);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
const define = easingDefines[name];
|
|
229
|
+
if (!define) {
|
|
230
|
+
throw new Error(`${name} 缓冲函数未定义`);
|
|
231
|
+
}
|
|
232
|
+
fn = bezier(...define);
|
|
233
|
+
}
|
|
234
|
+
return (input) => fn(Math.max(0, Math.min(input, 1)));
|
|
235
|
+
}
|
|
59
236
|
|
|
60
237
|
/**
|
|
61
238
|
* 判断对象是否为纯对象
|
|
@@ -72,15 +249,6 @@
|
|
|
72
249
|
// 是否对象直接实例
|
|
73
250
|
return proto === Object.prototype;
|
|
74
251
|
};
|
|
75
|
-
/**
|
|
76
|
-
* 判断对象内是否有该静态属性
|
|
77
|
-
* @param {object} obj
|
|
78
|
-
* @param {string} key
|
|
79
|
-
* @returns {boolean}
|
|
80
|
-
*/
|
|
81
|
-
function objectHas(obj, key) {
|
|
82
|
-
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
83
|
-
}
|
|
84
252
|
/**
|
|
85
253
|
* 遍历对象,返回 false 中断遍历
|
|
86
254
|
* @param {O} obj
|
|
@@ -234,23 +402,23 @@
|
|
|
234
402
|
let i = 0;
|
|
235
403
|
for (let len = keyArr.length; i < len - 1; ++i) {
|
|
236
404
|
const key = keyArr[i];
|
|
237
|
-
if (key
|
|
238
|
-
|
|
405
|
+
if (isNumber(Number(key)) && Array.isArray(tempObj)) {
|
|
406
|
+
tempObj = tempObj[key];
|
|
407
|
+
}
|
|
408
|
+
else if (isObject(tempObj) && objectHas(tempObj, key)) {
|
|
239
409
|
tempObj = tempObj[key];
|
|
240
410
|
}
|
|
241
411
|
else {
|
|
242
412
|
tempObj = undefined;
|
|
243
413
|
if (strict) {
|
|
244
|
-
throw new Error('[
|
|
414
|
+
throw new Error('[Object] objectGet path 路径不正确');
|
|
245
415
|
}
|
|
246
416
|
break;
|
|
247
417
|
}
|
|
248
418
|
}
|
|
249
419
|
return {
|
|
250
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
251
420
|
p: tempObj,
|
|
252
421
|
k: tempObj ? keyArr[i] : undefined,
|
|
253
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
|
254
422
|
v: tempObj ? tempObj[keyArr[i]] : undefined
|
|
255
423
|
};
|
|
256
424
|
}
|
|
@@ -278,135 +446,6 @@
|
|
|
278
446
|
return cloneObj;
|
|
279
447
|
}
|
|
280
448
|
|
|
281
|
-
/**
|
|
282
|
-
* 判断一个对象是否为类数组
|
|
283
|
-
*
|
|
284
|
-
* @param any
|
|
285
|
-
* @returns {boolean}
|
|
286
|
-
*/
|
|
287
|
-
function arrayLike(any) {
|
|
288
|
-
if (isArray(any))
|
|
289
|
-
return true;
|
|
290
|
-
if (isString(any))
|
|
291
|
-
return true;
|
|
292
|
-
if (!isObject(any))
|
|
293
|
-
return false;
|
|
294
|
-
return objectHas(any, 'length');
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* 遍历数组,返回 false 中断遍历(支持continue和break操作)
|
|
298
|
-
*
|
|
299
|
-
* @param {ArrayLike<V>} array
|
|
300
|
-
* @param {(val: V, idx: number) => any} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
|
|
301
|
-
* @param {boolean} reverse 是否倒序
|
|
302
|
-
* @returns {*}
|
|
303
|
-
*/
|
|
304
|
-
function arrayEach(array, iterator, reverse = false) {
|
|
305
|
-
if (reverse) {
|
|
306
|
-
for (let idx = array.length - 1; idx >= 0; idx--) {
|
|
307
|
-
const val = array[idx];
|
|
308
|
-
const re = iterator(val, idx, array);
|
|
309
|
-
if (re === false)
|
|
310
|
-
break;
|
|
311
|
-
else if (re === true)
|
|
312
|
-
continue;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
for (let idx = 0; idx < array.length; idx++) {
|
|
317
|
-
const val = array[idx];
|
|
318
|
-
const re = iterator(val, idx, array);
|
|
319
|
-
if (re === false)
|
|
320
|
-
break;
|
|
321
|
-
else if (re === true)
|
|
322
|
-
continue;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* 异步遍历数组,返回 false 中断遍历
|
|
328
|
-
* @param {ArrayLike<V>} array 数组
|
|
329
|
-
* @param {(val: V, idx: number) => Promise<any>} iterator 支持Promise类型的回调函数
|
|
330
|
-
* @param {boolean} reverse 是否反向遍历
|
|
331
|
-
*/
|
|
332
|
-
async function arrayEachAsync(array, iterator, reverse = false) {
|
|
333
|
-
if (reverse) {
|
|
334
|
-
for (let idx = array.length - 1; idx >= 0; idx--) {
|
|
335
|
-
const val = array[idx];
|
|
336
|
-
if ((await iterator(val, idx)) === false)
|
|
337
|
-
break;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
else {
|
|
341
|
-
for (let idx = 0; idx < array.length; idx++) {
|
|
342
|
-
const val = array[idx];
|
|
343
|
-
if ((await iterator(val, idx)) === false)
|
|
344
|
-
break;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* 插入到目标位置之前
|
|
350
|
-
* @param {AnyArray} array
|
|
351
|
-
* @param {number} start
|
|
352
|
-
* @param {number} to
|
|
353
|
-
* @returns {*}
|
|
354
|
-
*/
|
|
355
|
-
function arrayInsertBefore(array, start, to) {
|
|
356
|
-
if (start === to || start + 1 === to)
|
|
357
|
-
return;
|
|
358
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
359
|
-
const [source] = array.splice(start, 1);
|
|
360
|
-
const insertIndex = to < start ? to : to - 1;
|
|
361
|
-
array.splice(insertIndex, 0, source);
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* 数组删除指定项目
|
|
365
|
-
* @param {V[]} array
|
|
366
|
-
* @param {(val: V, idx: number) => boolean} expect
|
|
367
|
-
* @returns {V[]}
|
|
368
|
-
*/
|
|
369
|
-
function arrayRemove(array, expect) {
|
|
370
|
-
const indexes = [];
|
|
371
|
-
// 这里重命名一下:是为了杜绝 jest 里的 expect 与之产生检查错误
|
|
372
|
-
// eslint 的 jest 语法检查是遇到 expect 函数就以为是单元测试
|
|
373
|
-
const _expect = expect;
|
|
374
|
-
arrayEach(array, (val, idx) => {
|
|
375
|
-
if (_expect(val, idx))
|
|
376
|
-
indexes.push(idx);
|
|
377
|
-
});
|
|
378
|
-
indexes.forEach((val, idx) => array.splice(val - idx, 1));
|
|
379
|
-
return array;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// @ref https://cubic-bezier.com/
|
|
383
|
-
const easingDefines = {
|
|
384
|
-
linear: [0, 0, 1, 1],
|
|
385
|
-
ease: [0.25, 0.1, 0.25, 1],
|
|
386
|
-
'ease-in': [0.42, 0, 1, 1],
|
|
387
|
-
'ease-out': [0, 0, 0.58, 1],
|
|
388
|
-
'ease-in-out': [0.42, 0, 0.58, 1]
|
|
389
|
-
};
|
|
390
|
-
/**
|
|
391
|
-
* 缓冲函数化,用于 js 计算缓冲进度
|
|
392
|
-
* @param {EasingNameOrDefine} [name=linear]
|
|
393
|
-
* @returns {EasingFunction}
|
|
394
|
-
*/
|
|
395
|
-
function easingFunctional(name) {
|
|
396
|
-
let fn;
|
|
397
|
-
if (isArray(name)) {
|
|
398
|
-
fn = bezier(...name);
|
|
399
|
-
}
|
|
400
|
-
else {
|
|
401
|
-
const define = easingDefines[name];
|
|
402
|
-
if (!define) {
|
|
403
|
-
throw new Error(`${name} 缓冲函数未定义`);
|
|
404
|
-
}
|
|
405
|
-
fn = bezier(...define);
|
|
406
|
-
}
|
|
407
|
-
return (input) => fn(Math.max(0, Math.min(input, 1)));
|
|
408
|
-
}
|
|
409
|
-
|
|
410
449
|
/**
|
|
411
450
|
* 将字符串转换为驼峰格式
|
|
412
451
|
* @param {string} string
|
|
@@ -913,7 +952,6 @@
|
|
|
913
952
|
* - DD:日
|
|
914
953
|
* - dd: 日
|
|
915
954
|
* - HH:时(24 小时制)
|
|
916
|
-
* - hh:时(12 小时制)
|
|
917
955
|
* - mm:分
|
|
918
956
|
* - ss:秒
|
|
919
957
|
* - SSS:毫秒
|
|
@@ -1226,7 +1264,7 @@
|
|
|
1226
1264
|
* @param {string} filename
|
|
1227
1265
|
* @param {Function} callback
|
|
1228
1266
|
*/
|
|
1229
|
-
function
|
|
1267
|
+
function crossOriginDownload(url, filename, callback) {
|
|
1230
1268
|
const xhr = new XMLHttpRequest();
|
|
1231
1269
|
xhr.open('GET', url, true);
|
|
1232
1270
|
xhr.responseType = 'blob';
|
|
@@ -1764,7 +1802,7 @@
|
|
|
1764
1802
|
throw new SyntaxError('当前环境下无法设置全局属性');
|
|
1765
1803
|
}
|
|
1766
1804
|
/**
|
|
1767
|
-
*
|
|
1805
|
+
* 获取全局变量
|
|
1768
1806
|
* @param {string | number | symbol} key
|
|
1769
1807
|
* @param val
|
|
1770
1808
|
*/
|
|
@@ -1852,7 +1890,7 @@
|
|
|
1852
1890
|
const supportBigInt = typeof BigInt !== 'undefined';
|
|
1853
1891
|
const jsbi = () => getGlobal('JSBI');
|
|
1854
1892
|
const toBigInt = (n) => (supportBigInt ? BigInt(n) : jsbi().BigInt(n));
|
|
1855
|
-
const divide = (x, y) => (supportBigInt ? x / y : jsbi().divide(x, y));
|
|
1893
|
+
const divide$1 = (x, y) => (supportBigInt ? x / y : jsbi().divide(x, y));
|
|
1856
1894
|
const remainder = (x, y) => (supportBigInt ? x % y : jsbi().remainder(x, y));
|
|
1857
1895
|
/**
|
|
1858
1896
|
* 将十进制转换成任意进制
|
|
@@ -1874,7 +1912,7 @@
|
|
|
1874
1912
|
const bigLength = toBigInt(length);
|
|
1875
1913
|
const execute = () => {
|
|
1876
1914
|
const y = Number(remainder(bigInt, bigLength));
|
|
1877
|
-
bigInt = divide(bigInt, bigLength);
|
|
1915
|
+
bigInt = divide$1(bigInt, bigLength);
|
|
1878
1916
|
ret.unshift(hexPool[y]);
|
|
1879
1917
|
if (bigInt > 0) {
|
|
1880
1918
|
execute();
|
|
@@ -2433,12 +2471,136 @@
|
|
|
2433
2471
|
return result;
|
|
2434
2472
|
}
|
|
2435
2473
|
|
|
2474
|
+
/**
|
|
2475
|
+
* 数值安全乘法
|
|
2476
|
+
* @param arg1 数值1
|
|
2477
|
+
* @param arg2 数值2
|
|
2478
|
+
*/
|
|
2479
|
+
const multiply = (arg1, arg2) => {
|
|
2480
|
+
let m = 0;
|
|
2481
|
+
const s1 = arg1.toString();
|
|
2482
|
+
const s2 = arg2.toString();
|
|
2483
|
+
if (s1.split('.')[1] !== undefined)
|
|
2484
|
+
m += s1.split('.')[1].length;
|
|
2485
|
+
if (s2.split('.')[1] !== undefined)
|
|
2486
|
+
m += s2.split('.')[1].length;
|
|
2487
|
+
return (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) / Math.pow(10, m);
|
|
2488
|
+
};
|
|
2489
|
+
/**
|
|
2490
|
+
* 数值安全加法
|
|
2491
|
+
* @param arg1 数值1
|
|
2492
|
+
* @param arg2 数值2
|
|
2493
|
+
*/
|
|
2494
|
+
const add = (arg1, arg2) => {
|
|
2495
|
+
let r1 = 0;
|
|
2496
|
+
let r2 = 0;
|
|
2497
|
+
let m = 0;
|
|
2498
|
+
try {
|
|
2499
|
+
r1 = arg1.toString().split('.')[1].length;
|
|
2500
|
+
}
|
|
2501
|
+
catch (e) {
|
|
2502
|
+
r1 = 0;
|
|
2503
|
+
}
|
|
2504
|
+
try {
|
|
2505
|
+
r2 = arg2.toString().split('.')[1].length;
|
|
2506
|
+
}
|
|
2507
|
+
catch (e) {
|
|
2508
|
+
r2 = 0;
|
|
2509
|
+
}
|
|
2510
|
+
m = 10 ** Math.max(r1, r2);
|
|
2511
|
+
return (multiply(arg1, m) + multiply(arg2, m)) / m;
|
|
2512
|
+
};
|
|
2513
|
+
/**
|
|
2514
|
+
* 数值安全减法
|
|
2515
|
+
* @param arg1 数值1
|
|
2516
|
+
* @param arg2 数值2
|
|
2517
|
+
*/
|
|
2518
|
+
const subtract = (arg1, arg2) => add(arg1, -arg2);
|
|
2519
|
+
/**
|
|
2520
|
+
* 数值安全除法
|
|
2521
|
+
* @param arg1 数值1
|
|
2522
|
+
* @param arg2 数值2
|
|
2523
|
+
*/
|
|
2524
|
+
const divide = (arg1, arg2) => {
|
|
2525
|
+
let t1 = 0;
|
|
2526
|
+
let t2 = 0;
|
|
2527
|
+
let r1 = 0;
|
|
2528
|
+
let r2 = 0;
|
|
2529
|
+
if (arg1.toString().split('.')[1] !== undefined)
|
|
2530
|
+
t1 = arg1.toString().split('.')[1].length;
|
|
2531
|
+
if (arg2.toString().split('.')[1] !== undefined)
|
|
2532
|
+
t2 = arg2.toString().split('.')[1].length;
|
|
2533
|
+
r1 = Number(arg1.toString().replace('.', ''));
|
|
2534
|
+
r2 = Number(arg2.toString().replace('.', ''));
|
|
2535
|
+
return (r1 / r2) * Math.pow(10, t2 - t1);
|
|
2536
|
+
};
|
|
2537
|
+
/**
|
|
2538
|
+
* Correct the given number to specifying significant digits.
|
|
2539
|
+
*
|
|
2540
|
+
* @param num The input number
|
|
2541
|
+
* @param precision An integer specifying the number of significant digits
|
|
2542
|
+
*
|
|
2543
|
+
* @example strip(0.09999999999999998) === 0.1 // true
|
|
2544
|
+
*/
|
|
2545
|
+
function strip(num, precision = 15) {
|
|
2546
|
+
return +parseFloat(Number(num).toPrecision(precision));
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
function stringToUint8Array(str) {
|
|
2550
|
+
const utf8 = encodeURIComponent(str); // 将字符串转换为 UTF-8 编码
|
|
2551
|
+
const uint8Array = new Uint8Array(utf8.length); // 创建 Uint8Array
|
|
2552
|
+
for (let i = 0; i < utf8.length; i++) {
|
|
2553
|
+
uint8Array[i] = utf8.charCodeAt(i); // 填充 Uint8Array
|
|
2554
|
+
}
|
|
2555
|
+
return uint8Array;
|
|
2556
|
+
}
|
|
2557
|
+
function uint8ArrayToString(uint8Array) {
|
|
2558
|
+
const utf8 = String.fromCharCode.apply(null, uint8Array); // 将 Uint8Array 转为字符串
|
|
2559
|
+
return decodeURIComponent(utf8); // 将 UTF-8 字符串解码回正常字符串
|
|
2560
|
+
}
|
|
2561
|
+
/**
|
|
2562
|
+
* 将base64编码的字符串转换为原始字符串,包括对中文内容的处理(高性能,且支持Web、Node、小程序等任意平台)
|
|
2563
|
+
* @param base64 base64编码的字符串
|
|
2564
|
+
* @returns 原始字符串,包括中文内容
|
|
2565
|
+
*/
|
|
2566
|
+
function decodeFromBase64(base64) {
|
|
2567
|
+
const binaryString = !isNullOrUnDef(getGlobal('atob')) ? getGlobal('atob')(base64) : weAtob(base64);
|
|
2568
|
+
const len = binaryString.length;
|
|
2569
|
+
const bytes = new Uint8Array(len);
|
|
2570
|
+
for (let i = 0; i < len; i++) {
|
|
2571
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
2572
|
+
}
|
|
2573
|
+
// 使用TextDecoder将Uint8Array转换为原始字符串,包括中文内容
|
|
2574
|
+
return !isNullOrUnDef(getGlobal('TextDecoder'))
|
|
2575
|
+
? new (getGlobal('TextDecoder'))('utf-8').decode(bytes)
|
|
2576
|
+
: uint8ArrayToString(bytes);
|
|
2577
|
+
}
|
|
2578
|
+
/**
|
|
2579
|
+
* 将原始字符串,包括中文内容,转换为base64编码的字符串(高性能,且支持Web、Node、小程序等任意平台)
|
|
2580
|
+
* @param rawStr 原始字符串,包括中文内容
|
|
2581
|
+
* @returns base64编码的字符串
|
|
2582
|
+
*/
|
|
2583
|
+
function encodeToBase64(rawStr) {
|
|
2584
|
+
const utf8Array = !isNullOrUnDef(getGlobal('TextEncoder'))
|
|
2585
|
+
? new (getGlobal('TextEncoder'))().encode(rawStr)
|
|
2586
|
+
: stringToUint8Array(rawStr);
|
|
2587
|
+
// 将 Uint8Array 转换为二进制字符串
|
|
2588
|
+
let binaryString = '';
|
|
2589
|
+
const len = utf8Array.length;
|
|
2590
|
+
for (let i = 0; i < len; i++) {
|
|
2591
|
+
binaryString += String.fromCharCode(utf8Array[i]);
|
|
2592
|
+
}
|
|
2593
|
+
// 将二进制字符串转换为base64编码的字符串
|
|
2594
|
+
return !isNullOrUnDef(getGlobal('btoa')) ? getGlobal('btoa')(binaryString) : weBtoa(binaryString);
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2436
2597
|
exports.HEX_POOL = HEX_POOL;
|
|
2437
2598
|
exports.STRING_ARABIC_NUMERALS = STRING_ARABIC_NUMERALS;
|
|
2438
2599
|
exports.STRING_LOWERCASE_ALPHA = STRING_LOWERCASE_ALPHA;
|
|
2439
2600
|
exports.STRING_POOL = STRING_POOL;
|
|
2440
2601
|
exports.STRING_UPPERCASE_ALPHA = STRING_UPPERCASE_ALPHA;
|
|
2441
2602
|
exports.UNIQUE_NUMBER_SAFE_LENGTH = UNIQUE_NUMBER_SAFE_LENGTH;
|
|
2603
|
+
exports.add = add;
|
|
2442
2604
|
exports.addClass = addClass;
|
|
2443
2605
|
exports.arrayEach = arrayEach;
|
|
2444
2606
|
exports.arrayEachAsync = arrayEachAsync;
|
|
@@ -2456,15 +2618,18 @@
|
|
|
2456
2618
|
exports.cookieGet = cookieGet;
|
|
2457
2619
|
exports.cookieSet = cookieSet;
|
|
2458
2620
|
exports.copyText = copyText;
|
|
2459
|
-
exports.
|
|
2621
|
+
exports.crossOriginDownload = crossOriginDownload;
|
|
2460
2622
|
exports.dateParse = dateParse;
|
|
2461
2623
|
exports.dateToEnd = dateToEnd;
|
|
2462
2624
|
exports.dateToStart = dateToStart;
|
|
2463
2625
|
exports.debounce = debounce;
|
|
2626
|
+
exports.decodeFromBase64 = decodeFromBase64;
|
|
2627
|
+
exports.divide = divide;
|
|
2464
2628
|
exports.downloadBlob = downloadBlob;
|
|
2465
2629
|
exports.downloadData = downloadData;
|
|
2466
2630
|
exports.downloadHref = downloadHref;
|
|
2467
2631
|
exports.downloadURL = downloadURL;
|
|
2632
|
+
exports.encodeToBase64 = encodeToBase64;
|
|
2468
2633
|
exports.flatTree = flatTree;
|
|
2469
2634
|
exports.forEachDeep = forEachDeep;
|
|
2470
2635
|
exports.forEachMap = forEachMap;
|
|
@@ -2483,6 +2648,7 @@
|
|
|
2483
2648
|
exports.isBoolean = isBoolean;
|
|
2484
2649
|
exports.isDate = isDate;
|
|
2485
2650
|
exports.isDomReady = isDomReady;
|
|
2651
|
+
exports.isEmpty = isEmpty;
|
|
2486
2652
|
exports.isError = isError;
|
|
2487
2653
|
exports.isFunction = isFunction;
|
|
2488
2654
|
exports.isJsonString = isJsonString;
|
|
@@ -2498,6 +2664,7 @@
|
|
|
2498
2664
|
exports.isSymbol = isSymbol;
|
|
2499
2665
|
exports.isUndefined = isUndefined;
|
|
2500
2666
|
exports.isValidDate = isValidDate;
|
|
2667
|
+
exports.multiply = multiply;
|
|
2501
2668
|
exports.numberAbbr = numberAbbr;
|
|
2502
2669
|
exports.numberToHex = numberToHex;
|
|
2503
2670
|
exports.objectAssign = objectAssign;
|
|
@@ -2531,6 +2698,8 @@
|
|
|
2531
2698
|
exports.stringFill = stringFill;
|
|
2532
2699
|
exports.stringFormat = stringFormat;
|
|
2533
2700
|
exports.stringKebabCase = stringKebabCase;
|
|
2701
|
+
exports.strip = strip;
|
|
2702
|
+
exports.subtract = subtract;
|
|
2534
2703
|
exports.supportCanvas = supportCanvas;
|
|
2535
2704
|
exports.throttle = throttle;
|
|
2536
2705
|
exports.tooltipEvent = tooltipEvent;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sculp-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"packageManager": "npm@8.19.2",
|
|
5
5
|
"description": "js工具库",
|
|
6
6
|
"scripts": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"release:major": "standard-version --release-as major",
|
|
20
20
|
"commit": "git-cz"
|
|
21
21
|
},
|
|
22
|
-
"author": "chendq <deqiaochen@
|
|
22
|
+
"author": "chendq <deqiaochen@gmail.com>",
|
|
23
23
|
"main": "lib/cjs/index.js",
|
|
24
24
|
"module": "lib/es/index.js",
|
|
25
25
|
"browser": "lib/umd/index.js",
|