sculp-js 0.0.2 → 0.1.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/LICENSE.md +1 -1
- package/README.md +19 -1
- package/lib/cjs/array.js +4 -33
- package/lib/cjs/async.js +1 -1
- package/lib/cjs/clipboard.js +1 -1
- package/lib/cjs/cookie.js +1 -1
- package/lib/cjs/date.js +13 -13
- package/lib/cjs/dom.js +13 -1
- package/lib/cjs/download.js +1 -1
- package/lib/cjs/easing.js +1 -1
- package/lib/cjs/file.js +1 -1
- package/lib/cjs/func.js +160 -0
- package/lib/cjs/index.js +24 -2
- package/lib/cjs/number.js +82 -0
- package/lib/cjs/object.js +3 -3
- package/lib/cjs/path.js +1 -1
- package/lib/cjs/qs.js +1 -1
- package/lib/cjs/random.js +72 -0
- package/lib/cjs/string.js +34 -1
- package/lib/cjs/type.js +2 -1
- package/lib/cjs/unique.js +83 -0
- package/lib/cjs/url.js +1 -1
- package/lib/cjs/watermark.js +1 -1
- package/lib/es/array.js +5 -33
- package/lib/es/async.js +1 -1
- package/lib/es/clipboard.js +1 -1
- package/lib/es/cookie.js +1 -1
- package/lib/es/date.js +13 -13
- package/lib/es/dom.js +13 -2
- package/lib/es/download.js +1 -1
- package/lib/es/easing.js +1 -1
- package/lib/es/file.js +1 -1
- package/lib/es/func.js +154 -0
- package/lib/es/index.js +9 -5
- package/lib/es/number.js +77 -0
- package/lib/es/object.js +2 -2
- package/lib/es/path.js +1 -1
- package/lib/es/qs.js +1 -1
- package/lib/es/random.js +67 -0
- package/lib/es/string.js +34 -2
- package/lib/es/type.js +2 -2
- package/lib/es/unique.js +79 -0
- package/lib/es/url.js +1 -1
- package/lib/es/watermark.js +1 -1
- package/lib/index.d.ts +141 -26
- package/lib/umd/index.js +415 -45
- package/package.json +34 -11
package/lib/umd/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v0.0
|
|
2
|
+
* sculp-js v0.1.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -274,14 +274,14 @@
|
|
|
274
274
|
if (reverse) {
|
|
275
275
|
for (let idx = array.length - 1; idx >= 0; idx--) {
|
|
276
276
|
const val = array[idx];
|
|
277
|
-
if (iterator(val, idx) === false)
|
|
277
|
+
if (iterator(val, idx, array) === false)
|
|
278
278
|
break;
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
281
|
else {
|
|
282
282
|
for (let idx = 0; idx < array.length; idx++) {
|
|
283
283
|
const val = array[idx];
|
|
284
|
-
if (iterator(val, idx) === false)
|
|
284
|
+
if (iterator(val, idx, array) === false)
|
|
285
285
|
break;
|
|
286
286
|
}
|
|
287
287
|
}
|
|
@@ -413,40 +413,12 @@
|
|
|
413
413
|
while (child && child.parentId) {
|
|
414
414
|
ids = [child.parentId, ...ids];
|
|
415
415
|
nodes = [child.parent, ...nodes];
|
|
416
|
-
child = flatArray.find(_ => _[id] === child.parentId);
|
|
416
|
+
child = flatArray.find(_ => _[id] === child.parentId); // eslint-disable-line
|
|
417
417
|
}
|
|
418
418
|
return [ids, nodes];
|
|
419
419
|
};
|
|
420
420
|
return getIds(toFlatArray(tree));
|
|
421
421
|
}
|
|
422
|
-
/**
|
|
423
|
-
* 异步ForEach函数
|
|
424
|
-
* @param {array} array
|
|
425
|
-
* @param {asyncFuntion} callback
|
|
426
|
-
* // asyncForEach 使用范例如下
|
|
427
|
-
// const start = async () => {
|
|
428
|
-
// await asyncForEach(result, async (item) => {
|
|
429
|
-
// await request(item);
|
|
430
|
-
// count++;
|
|
431
|
-
// });
|
|
432
|
-
|
|
433
|
-
// console.log('发送次数', count);
|
|
434
|
-
// }
|
|
435
|
-
|
|
436
|
-
// for await...of 使用范例如下
|
|
437
|
-
// const loadImages = async (images) => {
|
|
438
|
-
// for await (const item of images) {
|
|
439
|
-
// await request(item);
|
|
440
|
-
// count++;
|
|
441
|
-
// }
|
|
442
|
-
// }
|
|
443
|
-
* @return {*}
|
|
444
|
-
*/
|
|
445
|
-
async function asyncForEach(array, callback) {
|
|
446
|
-
for (let index = 0, len = array.length; index < len; index++) {
|
|
447
|
-
await callback(array[index], index, array);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
422
|
|
|
451
423
|
// @ref https://cubic-bezier.com/
|
|
452
424
|
const easingDefines = {
|
|
@@ -592,6 +564,36 @@
|
|
|
592
564
|
* @returns {string}
|
|
593
565
|
*/
|
|
594
566
|
const stringFill = (length, value = ' ') => new Array(length).fill(value).join('');
|
|
567
|
+
/**
|
|
568
|
+
* 字符串的像素宽度
|
|
569
|
+
* @param {string} str 目标字符串
|
|
570
|
+
* @param {number} fontSize 字符串字体大小
|
|
571
|
+
* @param {boolean} isRemoveDom 计算后是否移除中间dom元素
|
|
572
|
+
* @return {*}
|
|
573
|
+
*/
|
|
574
|
+
function getStrWidthPx(str, fontSize = 14, isRemoveDom = false) {
|
|
575
|
+
let strWidth = 0;
|
|
576
|
+
console.assert(isString(str), `${str} 不是有效的字符串`);
|
|
577
|
+
if (isString(str) && str.length > 0) {
|
|
578
|
+
let getEle = document.querySelector('#getStrWidth1494304949567');
|
|
579
|
+
if (!getEle) {
|
|
580
|
+
const _ele = document.createElement('span');
|
|
581
|
+
_ele.id = 'getStrWidth1494304949567';
|
|
582
|
+
_ele.style.fontSize = fontSize + 'px';
|
|
583
|
+
_ele.style.whiteSpace = 'nowrap';
|
|
584
|
+
_ele.style.visibility = 'hidden';
|
|
585
|
+
_ele.textContent = str;
|
|
586
|
+
document.body.appendChild(_ele);
|
|
587
|
+
getEle = _ele;
|
|
588
|
+
}
|
|
589
|
+
getEle.textContent = str;
|
|
590
|
+
strWidth = getEle.offsetWidth;
|
|
591
|
+
if (isRemoveDom) {
|
|
592
|
+
document.body.appendChild(getEle);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return strWidth;
|
|
596
|
+
}
|
|
595
597
|
|
|
596
598
|
/**
|
|
597
599
|
* 判断元素是否包含某个样式名
|
|
@@ -722,6 +724,17 @@
|
|
|
722
724
|
domReadyCallbacks.push(callback);
|
|
723
725
|
}
|
|
724
726
|
}
|
|
727
|
+
/**
|
|
728
|
+
* 获取元素样式属性的计算值
|
|
729
|
+
* @param {HTMLElement} el
|
|
730
|
+
* @param {string} property
|
|
731
|
+
* @param {boolean} reNumber
|
|
732
|
+
* @return {string|number}
|
|
733
|
+
*/
|
|
734
|
+
function getComputedCssVal(el, property, reNumber = true) {
|
|
735
|
+
const originVal = getComputedStyle(el).getPropertyValue(property) ?? '';
|
|
736
|
+
return reNumber ? Number(originVal.replace(/([0-9]*)(.*)/g, '$1')) : originVal;
|
|
737
|
+
}
|
|
725
738
|
|
|
726
739
|
const textEl = document.createElement('textarea');
|
|
727
740
|
setStyle(textEl, {
|
|
@@ -848,16 +861,16 @@
|
|
|
848
861
|
*/
|
|
849
862
|
function calculateDate(strDate, n, sep = '-') {
|
|
850
863
|
//strDate 为字符串日期 如:'2019-01-01' n为你要传入的参数,当前为0,前一天为-1,后一天为1
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
864
|
+
const dateArr = strDate.split(sep); //这边给定一个特定时间
|
|
865
|
+
const newDate = new Date(+dateArr[0], +dateArr[1] - 1, +dateArr[2]);
|
|
866
|
+
const befminuts = newDate.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
|
|
867
|
+
const beforeDat = new Date();
|
|
855
868
|
beforeDat.setTime(befminuts);
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
869
|
+
const befMonth = beforeDat.getMonth() + 1;
|
|
870
|
+
const mon = befMonth >= 10 ? befMonth : '0' + befMonth;
|
|
871
|
+
const befDate = beforeDat.getDate();
|
|
872
|
+
const da = befDate >= 10 ? befDate : '0' + befDate;
|
|
873
|
+
const finalNewDate = beforeDat.getFullYear() + '-' + mon + '-' + da;
|
|
861
874
|
return finalNewDate;
|
|
862
875
|
}
|
|
863
876
|
/**
|
|
@@ -868,9 +881,9 @@
|
|
|
868
881
|
* @return {*}
|
|
869
882
|
*/
|
|
870
883
|
function calculateDateTime(n, dateSep = '-', timeSep = ':') {
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
884
|
+
const date = new Date();
|
|
885
|
+
const separator1 = '-';
|
|
886
|
+
const separator2 = ':';
|
|
874
887
|
let year = date.getFullYear();
|
|
875
888
|
let month = date.getMonth() + 1;
|
|
876
889
|
let strDate = date.getDate() + n;
|
|
@@ -1308,16 +1321,357 @@
|
|
|
1308
1321
|
// 调用
|
|
1309
1322
|
// __canvasWM({ content: 'QQMusicFE' })
|
|
1310
1323
|
|
|
1324
|
+
/**
|
|
1325
|
+
* 防抖函数
|
|
1326
|
+
* 当函数被连续调用时,该函数并不执行,只有当其全部停止调用超过一定时间后才执行1次。
|
|
1327
|
+
* 例如:上电梯的时候,大家陆陆续续进来,电梯的门不会关上,只有当一段时间都没有人上来,电梯才会关门。
|
|
1328
|
+
* @param {F} func
|
|
1329
|
+
* @param {number} wait
|
|
1330
|
+
* @returns {DebounceFunc<F>}
|
|
1331
|
+
*/
|
|
1332
|
+
const debounce = (func, wait) => {
|
|
1333
|
+
let timeout;
|
|
1334
|
+
let canceled = false;
|
|
1335
|
+
const f = function (...args) {
|
|
1336
|
+
if (canceled)
|
|
1337
|
+
return;
|
|
1338
|
+
clearTimeout(timeout);
|
|
1339
|
+
timeout = setTimeout(() => {
|
|
1340
|
+
func.call(this, ...args);
|
|
1341
|
+
}, wait);
|
|
1342
|
+
};
|
|
1343
|
+
f.cancel = () => {
|
|
1344
|
+
clearTimeout(timeout);
|
|
1345
|
+
canceled = true;
|
|
1346
|
+
};
|
|
1347
|
+
return f;
|
|
1348
|
+
};
|
|
1349
|
+
/**
|
|
1350
|
+
* 节流函数
|
|
1351
|
+
* 节流就是节约流量,将连续触发的事件稀释成预设评率。 比如每间隔1秒执行一次函数,无论这期间触发多少次事件。
|
|
1352
|
+
* 这有点像公交车,无论在站点等车的人多不多,公交车只会按时来一班,不会来一个人就来一辆公交车。
|
|
1353
|
+
* @param {F} func
|
|
1354
|
+
* @param {number} wait
|
|
1355
|
+
* @param {boolean} immediate
|
|
1356
|
+
* @returns {ThrottleFunc<F>}
|
|
1357
|
+
*/
|
|
1358
|
+
const throttle = (func, wait, immediate) => {
|
|
1359
|
+
let timeout;
|
|
1360
|
+
let canceled = false;
|
|
1361
|
+
let lastCalledTime = 0;
|
|
1362
|
+
const f = function (...args) {
|
|
1363
|
+
if (canceled)
|
|
1364
|
+
return;
|
|
1365
|
+
const now = Date.now();
|
|
1366
|
+
const call = () => {
|
|
1367
|
+
lastCalledTime = now;
|
|
1368
|
+
func.call(this, ...args);
|
|
1369
|
+
};
|
|
1370
|
+
// 第一次执行
|
|
1371
|
+
if (lastCalledTime === 0) {
|
|
1372
|
+
if (immediate) {
|
|
1373
|
+
return call();
|
|
1374
|
+
}
|
|
1375
|
+
else {
|
|
1376
|
+
lastCalledTime = now;
|
|
1377
|
+
return;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
const remain = lastCalledTime + wait - now;
|
|
1381
|
+
if (remain > 0) {
|
|
1382
|
+
clearTimeout(timeout);
|
|
1383
|
+
timeout = setTimeout(() => call(), wait);
|
|
1384
|
+
}
|
|
1385
|
+
else {
|
|
1386
|
+
call();
|
|
1387
|
+
}
|
|
1388
|
+
};
|
|
1389
|
+
f.cancel = () => {
|
|
1390
|
+
clearTimeout(timeout);
|
|
1391
|
+
canceled = true;
|
|
1392
|
+
};
|
|
1393
|
+
return f;
|
|
1394
|
+
};
|
|
1395
|
+
/**
|
|
1396
|
+
* 单次函数
|
|
1397
|
+
* @param {AnyFunc} func
|
|
1398
|
+
* @returns {AnyFunc}
|
|
1399
|
+
*/
|
|
1400
|
+
const once = (func) => {
|
|
1401
|
+
let called = false;
|
|
1402
|
+
let result;
|
|
1403
|
+
return function (...args) {
|
|
1404
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
1405
|
+
if (called)
|
|
1406
|
+
return result;
|
|
1407
|
+
called = true;
|
|
1408
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1409
|
+
result = func.call(this, ...args);
|
|
1410
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
1411
|
+
return result;
|
|
1412
|
+
};
|
|
1413
|
+
};
|
|
1414
|
+
/**
|
|
1415
|
+
* 设置全局变量
|
|
1416
|
+
* @param {string | number | symbol} key
|
|
1417
|
+
* @param val
|
|
1418
|
+
*/
|
|
1419
|
+
function setGlobal(key, val) {
|
|
1420
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1421
|
+
// @ts-ignore
|
|
1422
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1423
|
+
if (typeof globalThis !== 'undefined')
|
|
1424
|
+
globalThis[key] = val;
|
|
1425
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1426
|
+
// @ts-ignore
|
|
1427
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1428
|
+
else if (typeof window !== 'undefined')
|
|
1429
|
+
window[key] = val;
|
|
1430
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1431
|
+
// @ts-ignore
|
|
1432
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1433
|
+
else if (typeof global !== 'undefined')
|
|
1434
|
+
global[key] = val;
|
|
1435
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1436
|
+
// @ts-ignore
|
|
1437
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1438
|
+
else if (typeof self !== 'undefined')
|
|
1439
|
+
self[key] = val;
|
|
1440
|
+
else
|
|
1441
|
+
throw new SyntaxError('当前环境下无法设置全局属性');
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* 设置全局变量
|
|
1445
|
+
* @param {string | number | symbol} key
|
|
1446
|
+
* @param val
|
|
1447
|
+
*/
|
|
1448
|
+
function getGlobal(key) {
|
|
1449
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1450
|
+
// @ts-ignore
|
|
1451
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1452
|
+
if (typeof globalThis !== 'undefined')
|
|
1453
|
+
return globalThis[key];
|
|
1454
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1455
|
+
// @ts-ignore
|
|
1456
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1457
|
+
else if (typeof window !== 'undefined')
|
|
1458
|
+
return window[key];
|
|
1459
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1460
|
+
// @ts-ignore
|
|
1461
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1462
|
+
else if (typeof global !== 'undefined')
|
|
1463
|
+
return global[key];
|
|
1464
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1465
|
+
// @ts-ignore
|
|
1466
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1467
|
+
else if (typeof self !== 'undefined')
|
|
1468
|
+
return self[key];
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
/**
|
|
1472
|
+
* 随机整数
|
|
1473
|
+
* @param {number} min
|
|
1474
|
+
* @param {number} max
|
|
1475
|
+
* @returns {number}
|
|
1476
|
+
*/
|
|
1477
|
+
const randomNumber = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
|
|
1478
|
+
const STRING_POOL = `${STRING_ARABIC_NUMERALS}${STRING_UPPERCASE_ALPHA}${STRING_LOWERCASE_ALPHA}`;
|
|
1479
|
+
/**
|
|
1480
|
+
* 随机字符串
|
|
1481
|
+
* @param {number | string} length
|
|
1482
|
+
* @param {string} pool
|
|
1483
|
+
* @returns {string}
|
|
1484
|
+
*/
|
|
1485
|
+
const randomString = (length, pool) => {
|
|
1486
|
+
let _length = 0;
|
|
1487
|
+
let _pool = STRING_POOL;
|
|
1488
|
+
if (isString(pool)) {
|
|
1489
|
+
_length = length;
|
|
1490
|
+
_pool = pool;
|
|
1491
|
+
}
|
|
1492
|
+
else if (isNumber(length)) {
|
|
1493
|
+
_length = length;
|
|
1494
|
+
}
|
|
1495
|
+
else if (isString(length)) {
|
|
1496
|
+
_pool = length;
|
|
1497
|
+
}
|
|
1498
|
+
let times = Math.max(_length, 1);
|
|
1499
|
+
let result = '';
|
|
1500
|
+
const min = 0;
|
|
1501
|
+
const max = _pool.length - 1;
|
|
1502
|
+
if (max < 2)
|
|
1503
|
+
throw new Error('字符串池长度不能少于 2');
|
|
1504
|
+
while (times--) {
|
|
1505
|
+
const index = randomNumber(min, max);
|
|
1506
|
+
result += _pool[index];
|
|
1507
|
+
}
|
|
1508
|
+
return result;
|
|
1509
|
+
};
|
|
1510
|
+
/**
|
|
1511
|
+
* 优先浏览器原生能力获取 UUID v4
|
|
1512
|
+
* @returns {string}
|
|
1513
|
+
*/
|
|
1514
|
+
function randomUuid() {
|
|
1515
|
+
if (typeof URL === 'undefined' || !URL.createObjectURL || typeof Blob === 'undefined') {
|
|
1516
|
+
const hex = '0123456789abcdef';
|
|
1517
|
+
const model = 'xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx';
|
|
1518
|
+
let str = '';
|
|
1519
|
+
for (let i = 0; i < model.length; i++) {
|
|
1520
|
+
const rnd = randomNumber(0, 15);
|
|
1521
|
+
str += model[i] == '-' || model[i] == '4' ? model[i] : hex[rnd];
|
|
1522
|
+
}
|
|
1523
|
+
return str;
|
|
1524
|
+
}
|
|
1525
|
+
return /[^/]+$/.exec(URL.createObjectURL(new Blob()).slice())[0];
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
const HEX_POOL = `${STRING_ARABIC_NUMERALS}${STRING_UPPERCASE_ALPHA}${STRING_LOWERCASE_ALPHA}`;
|
|
1529
|
+
const supportBigInt = typeof BigInt !== 'undefined';
|
|
1530
|
+
const jsbi = () => getGlobal('JSBI');
|
|
1531
|
+
const toBigInt = (n) => (supportBigInt ? BigInt(n) : jsbi().BigInt(n));
|
|
1532
|
+
const divide = (x, y) => (supportBigInt ? x / y : jsbi().divide(x, y));
|
|
1533
|
+
const remainder = (x, y) => (supportBigInt ? x % y : jsbi().remainder(x, y));
|
|
1534
|
+
/**
|
|
1535
|
+
* 将十进制转换成任意进制
|
|
1536
|
+
* @param {number | string} decimal 十进制数值或字符串,可以是任意长度,会使用大数进行计算
|
|
1537
|
+
* @param {string} [hexPool] 进制池,默认 62 进制
|
|
1538
|
+
* @returns {string}
|
|
1539
|
+
*/
|
|
1540
|
+
const numberToHex = (decimal, hexPool = HEX_POOL) => {
|
|
1541
|
+
if (hexPool.length < 2)
|
|
1542
|
+
throw new Error('进制池长度不能少于 2');
|
|
1543
|
+
if (!supportBigInt) {
|
|
1544
|
+
throw new Error('需要安装 jsbi 模块并将 JSBI 设置为全局变量:\nimport JSBI from "jsbi"; window.JSBI = JSBI;');
|
|
1545
|
+
}
|
|
1546
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1547
|
+
let bigInt = toBigInt(decimal);
|
|
1548
|
+
const ret = [];
|
|
1549
|
+
const { length } = hexPool;
|
|
1550
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1551
|
+
const bigLength = toBigInt(length);
|
|
1552
|
+
const execute = () => {
|
|
1553
|
+
const y = Number(remainder(bigInt, bigLength));
|
|
1554
|
+
bigInt = divide(bigInt, bigLength);
|
|
1555
|
+
ret.unshift(hexPool[y]);
|
|
1556
|
+
if (bigInt > 0) {
|
|
1557
|
+
execute();
|
|
1558
|
+
}
|
|
1559
|
+
};
|
|
1560
|
+
execute();
|
|
1561
|
+
return ret.join('');
|
|
1562
|
+
};
|
|
1563
|
+
/**
|
|
1564
|
+
* 缩写
|
|
1565
|
+
* @param {number | string} num
|
|
1566
|
+
* @param {Array<string>} units
|
|
1567
|
+
* @param {number} ratio
|
|
1568
|
+
* @param {number} exponent
|
|
1569
|
+
* @returns {string}
|
|
1570
|
+
*/
|
|
1571
|
+
const numberAbbr = (num, units, ratio = 1000, exponent) => {
|
|
1572
|
+
const { length } = units;
|
|
1573
|
+
if (length === 0)
|
|
1574
|
+
throw new Error('至少需要一个单位');
|
|
1575
|
+
let num2 = Number(num);
|
|
1576
|
+
let times = 0;
|
|
1577
|
+
while (num2 >= ratio && times < length - 1) {
|
|
1578
|
+
num2 = num2 / ratio;
|
|
1579
|
+
times++;
|
|
1580
|
+
}
|
|
1581
|
+
const value = num2.toFixed(exponent);
|
|
1582
|
+
const unit = units[times];
|
|
1583
|
+
return value.toString() + '' + unit;
|
|
1584
|
+
};
|
|
1585
|
+
/**
|
|
1586
|
+
* 将数字格式化成千位分隔符显示的字符串
|
|
1587
|
+
* @param {number} val 数字
|
|
1588
|
+
* @param {'int' | 'float'} type 展示分段显示的类型 int:整型 | float:浮点型
|
|
1589
|
+
* @return {string}
|
|
1590
|
+
*/
|
|
1591
|
+
function formatNumber(val, type = 'int') {
|
|
1592
|
+
return type === 'int' ? parseInt(String(val)).toLocaleString() : Number(val).toLocaleString('en-US');
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
const padStartWithZero = (str, maxLength = 2) => String(str).padStart(maxLength, '0');
|
|
1596
|
+
let safeNo = 0;
|
|
1597
|
+
let lastTimestamp = 0;
|
|
1598
|
+
// 安全后缀长度,按 1 毫秒运算 99999 次 JS 代码来进行估算
|
|
1599
|
+
// 那么,补足长度为 5
|
|
1600
|
+
// 时间戳模式长度为 13
|
|
1601
|
+
// 取最长 5 + 13 = 18
|
|
1602
|
+
const UNIQUE_NUMBER_SAFE_LENGTH = 18;
|
|
1603
|
+
const FIX_SAFE_LENGTH = 5;
|
|
1604
|
+
const TIMESTAMP_LENGTH = 13;
|
|
1605
|
+
/**
|
|
1606
|
+
* 生成唯一不重复数值
|
|
1607
|
+
* @param {number} length
|
|
1608
|
+
* @returns {string}
|
|
1609
|
+
*/
|
|
1610
|
+
const uniqueNumber = (length = UNIQUE_NUMBER_SAFE_LENGTH) => {
|
|
1611
|
+
const now = Date.now();
|
|
1612
|
+
length = Math.max(length, UNIQUE_NUMBER_SAFE_LENGTH);
|
|
1613
|
+
if (now !== lastTimestamp) {
|
|
1614
|
+
lastTimestamp = now;
|
|
1615
|
+
safeNo = 0;
|
|
1616
|
+
}
|
|
1617
|
+
const timestamp = `${now}`;
|
|
1618
|
+
let random = '';
|
|
1619
|
+
const rndLength = length - FIX_SAFE_LENGTH - TIMESTAMP_LENGTH;
|
|
1620
|
+
if (rndLength > 0) {
|
|
1621
|
+
const rndMin = 10 ** (rndLength - 1);
|
|
1622
|
+
const rndMax = 10 ** rndLength - 1;
|
|
1623
|
+
const rnd = randomNumber(rndMin, rndMax);
|
|
1624
|
+
random = `${rnd}`;
|
|
1625
|
+
}
|
|
1626
|
+
const safe = padStartWithZero(safeNo, FIX_SAFE_LENGTH);
|
|
1627
|
+
safeNo++;
|
|
1628
|
+
return `${timestamp}${random}${safe}`;
|
|
1629
|
+
};
|
|
1630
|
+
const randomFromPool = (pool) => {
|
|
1631
|
+
const poolIndex = randomNumber(0, pool.length - 1);
|
|
1632
|
+
return pool[poolIndex];
|
|
1633
|
+
};
|
|
1634
|
+
/**
|
|
1635
|
+
* 生成唯一不重复字符串
|
|
1636
|
+
* @param {number | string} length
|
|
1637
|
+
* @param {string} pool
|
|
1638
|
+
* @returns {string}
|
|
1639
|
+
*/
|
|
1640
|
+
const uniqueString = (length, pool) => {
|
|
1641
|
+
let _length = 0;
|
|
1642
|
+
let _pool = HEX_POOL;
|
|
1643
|
+
if (isString(pool)) {
|
|
1644
|
+
_length = length;
|
|
1645
|
+
_pool = pool;
|
|
1646
|
+
}
|
|
1647
|
+
else if (isNumber(length)) {
|
|
1648
|
+
_length = length;
|
|
1649
|
+
}
|
|
1650
|
+
else if (isString(length)) {
|
|
1651
|
+
_pool = length;
|
|
1652
|
+
}
|
|
1653
|
+
let uniqueString = numberToHex(uniqueNumber(), _pool);
|
|
1654
|
+
let insertLength = _length - uniqueString.length;
|
|
1655
|
+
if (insertLength <= 0)
|
|
1656
|
+
return uniqueString;
|
|
1657
|
+
while (insertLength--) {
|
|
1658
|
+
uniqueString += randomFromPool(_pool);
|
|
1659
|
+
}
|
|
1660
|
+
return uniqueString;
|
|
1661
|
+
};
|
|
1662
|
+
|
|
1663
|
+
exports.HEX_POOL = HEX_POOL;
|
|
1311
1664
|
exports.STRING_ARABIC_NUMERALS = STRING_ARABIC_NUMERALS;
|
|
1312
1665
|
exports.STRING_LOWERCASE_ALPHA = STRING_LOWERCASE_ALPHA;
|
|
1666
|
+
exports.STRING_POOL = STRING_POOL;
|
|
1313
1667
|
exports.STRING_UPPERCASE_ALPHA = STRING_UPPERCASE_ALPHA;
|
|
1668
|
+
exports.UNIQUE_NUMBER_SAFE_LENGTH = UNIQUE_NUMBER_SAFE_LENGTH;
|
|
1314
1669
|
exports.addClass = addClass;
|
|
1315
1670
|
exports.arrayEach = arrayEach;
|
|
1316
1671
|
exports.arrayEachAsync = arrayEachAsync;
|
|
1317
1672
|
exports.arrayInsertBefore = arrayInsertBefore;
|
|
1318
1673
|
exports.arrayLike = arrayLike;
|
|
1319
1674
|
exports.arrayRemove = arrayRemove;
|
|
1320
|
-
exports.asyncForEach = asyncForEach;
|
|
1321
1675
|
exports.asyncMap = asyncMap;
|
|
1322
1676
|
exports.calculateDate = calculateDate;
|
|
1323
1677
|
exports.calculateDateTime = calculateDateTime;
|
|
@@ -1327,13 +1681,18 @@
|
|
|
1327
1681
|
exports.cookieGet = cookieGet;
|
|
1328
1682
|
exports.cookieSet = cookieSet;
|
|
1329
1683
|
exports.copyText = copyText;
|
|
1684
|
+
exports.debounce = debounce;
|
|
1330
1685
|
exports.deepTraversal = deepTraversal;
|
|
1331
1686
|
exports.downloadBlob = downloadBlob;
|
|
1332
1687
|
exports.downloadData = downloadData;
|
|
1333
1688
|
exports.downloadHref = downloadHref;
|
|
1334
1689
|
exports.downloadURL = downloadURL;
|
|
1335
1690
|
exports.formatDate = formatDate;
|
|
1691
|
+
exports.formatNumber = formatNumber;
|
|
1336
1692
|
exports.genCanvasWM = genCanvasWM;
|
|
1693
|
+
exports.getComputedCssVal = getComputedCssVal;
|
|
1694
|
+
exports.getGlobal = getGlobal;
|
|
1695
|
+
exports.getStrWidthPx = getStrWidthPx;
|
|
1337
1696
|
exports.getStyle = getStyle;
|
|
1338
1697
|
exports.getTreeIds = getTreeIds;
|
|
1339
1698
|
exports.hasClass = hasClass;
|
|
@@ -1354,6 +1713,8 @@
|
|
|
1354
1713
|
exports.isString = isString;
|
|
1355
1714
|
exports.isSymbol = isSymbol;
|
|
1356
1715
|
exports.isUndefined = isUndefined;
|
|
1716
|
+
exports.numberAbbr = numberAbbr;
|
|
1717
|
+
exports.numberToHex = numberToHex;
|
|
1357
1718
|
exports.objectAssign = objectAssign;
|
|
1358
1719
|
exports.objectEach = objectEach;
|
|
1359
1720
|
exports.objectEachAsync = objectEachAsync;
|
|
@@ -1365,11 +1726,16 @@
|
|
|
1365
1726
|
exports.objectOmit = objectOmit;
|
|
1366
1727
|
exports.objectPick = objectPick;
|
|
1367
1728
|
exports.onDomReady = onDomReady;
|
|
1729
|
+
exports.once = once;
|
|
1368
1730
|
exports.pathJoin = pathJoin;
|
|
1369
1731
|
exports.pathNormalize = pathNormalize;
|
|
1370
1732
|
exports.qsParse = qsParse;
|
|
1371
1733
|
exports.qsStringify = qsStringify;
|
|
1734
|
+
exports.randomNumber = randomNumber;
|
|
1735
|
+
exports.randomString = randomString;
|
|
1736
|
+
exports.randomUuid = randomUuid;
|
|
1372
1737
|
exports.removeClass = removeClass;
|
|
1738
|
+
exports.setGlobal = setGlobal;
|
|
1373
1739
|
exports.setStyle = setStyle;
|
|
1374
1740
|
exports.smoothScroll = smoothScroll;
|
|
1375
1741
|
exports.stringAssign = stringAssign;
|
|
@@ -1378,6 +1744,10 @@
|
|
|
1378
1744
|
exports.stringFill = stringFill;
|
|
1379
1745
|
exports.stringFormat = stringFormat;
|
|
1380
1746
|
exports.stringKebabCase = stringKebabCase;
|
|
1747
|
+
exports.throttle = throttle;
|
|
1748
|
+
exports.typeIs = typeIs;
|
|
1749
|
+
exports.uniqueNumber = uniqueNumber;
|
|
1750
|
+
exports.uniqueString = uniqueString;
|
|
1381
1751
|
exports.urlDelParams = urlDelParams;
|
|
1382
1752
|
exports.urlParse = urlParse;
|
|
1383
1753
|
exports.urlSetParams = urlSetParams;
|
package/package.json
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sculp-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "js工具库",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"
|
|
8
|
-
"build": "
|
|
7
|
+
"prepare": "husky install",
|
|
8
|
+
"build": "NODE_OPTIONS=--max-old-space-size=2048 rollup --bundleConfigAsCjs --config rollup.config.js",
|
|
9
|
+
"build:terser": "node scripts/build.js",
|
|
9
10
|
"test:unit": "jest",
|
|
10
11
|
"test": "jest --coverage",
|
|
11
|
-
"
|
|
12
|
+
"lint": "eslint ./src --ext .vue,.js,jsx,.ts,tsx",
|
|
13
|
+
"lint:fix": "eslint --fix ./src --ext .vue,.js,jsx,.ts,tsx",
|
|
14
|
+
"prettier": "prettier -c --write \"**/*.{vue,ts,js,jsx,css,less,scss,json}\"",
|
|
15
|
+
"release:patch": "standard-version --release-as patch",
|
|
16
|
+
"release:minor": "standard-version --release-as minor",
|
|
17
|
+
"release:major": "standard-version --release-as major",
|
|
18
|
+
"commit": "git-cz"
|
|
12
19
|
},
|
|
13
20
|
"author": "chendq <deqiaochen@foxmail.com>",
|
|
14
21
|
"main": "lib/cjs/index.js",
|
|
15
22
|
"module": "lib/es/index.js",
|
|
16
23
|
"browser": "lib/umd/index.js",
|
|
17
24
|
"types": "lib/index.d.ts",
|
|
18
|
-
"type": "module",
|
|
19
25
|
"exports": {
|
|
20
26
|
".": {
|
|
21
27
|
"import": "./lib/es/index.js",
|
|
@@ -25,9 +31,7 @@
|
|
|
25
31
|
},
|
|
26
32
|
"sideEffects": false,
|
|
27
33
|
"files": [
|
|
28
|
-
"lib"
|
|
29
|
-
"lib/cjs",
|
|
30
|
-
"lib/index.d.ts"
|
|
34
|
+
"lib"
|
|
31
35
|
],
|
|
32
36
|
"keywords": [
|
|
33
37
|
"js-utils",
|
|
@@ -54,8 +58,10 @@
|
|
|
54
58
|
"@rollup/plugin-typescript": "^11.1.5",
|
|
55
59
|
"@types/jest": "^29.5.5",
|
|
56
60
|
"@typescript-eslint/eslint-plugin": "^6.7.5",
|
|
57
|
-
"@typescript-eslint/parser": "^6.
|
|
61
|
+
"@typescript-eslint/parser": "^6.8.0",
|
|
62
|
+
"commitizen": "^4.3.0",
|
|
58
63
|
"cross-env": "^7.0.3",
|
|
64
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
59
65
|
"eslint": "^8.51.0",
|
|
60
66
|
"eslint-config-prettier": "^9.0.0",
|
|
61
67
|
"eslint-config-standard": "^17.1.0",
|
|
@@ -73,11 +79,28 @@
|
|
|
73
79
|
"rollup-plugin-clear": "^2.0.7",
|
|
74
80
|
"rollup-plugin-dts": "^6.1.0",
|
|
75
81
|
"rollup-plugin-subpath-externals": "^3.4.0",
|
|
76
|
-
"
|
|
82
|
+
"standard-version": "^9.5.0",
|
|
83
|
+
"stylelint": "14.16",
|
|
77
84
|
"stylelint-config-css-modules": "^4.3.0",
|
|
78
85
|
"stylelint-config-prettier": "^9.0.5",
|
|
79
|
-
"stylelint-config-standard": "^
|
|
86
|
+
"stylelint-config-standard": "^20.0.0",
|
|
80
87
|
"ts-loader": "^9.5.0",
|
|
81
88
|
"typescript": "^5.2.2"
|
|
89
|
+
},
|
|
90
|
+
"config": {
|
|
91
|
+
"commitizen": {
|
|
92
|
+
"path": "./node_modules/cz-conventional-changelog"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"lint-staged": {
|
|
96
|
+
"*.[tj]s?(x)": [
|
|
97
|
+
"eslint --fix"
|
|
98
|
+
],
|
|
99
|
+
"*.vue": [
|
|
100
|
+
"eslint --fix"
|
|
101
|
+
],
|
|
102
|
+
"*.{css,less,scss,json,md}": [
|
|
103
|
+
"prettier --write"
|
|
104
|
+
]
|
|
82
105
|
}
|
|
83
106
|
}
|