sculp-js 1.9.0 → 1.10.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 +18 -1
- package/lib/cjs/async.js +1 -1
- package/lib/cjs/base64.js +1 -1
- package/lib/cjs/clipboard.js +1 -1
- package/lib/cjs/cloneDeep.js +1 -1
- package/lib/cjs/cookie.js +1 -1
- package/lib/cjs/date.js +1 -1
- package/lib/cjs/dom.js +11 -7
- package/lib/cjs/download.js +1 -1
- package/lib/cjs/easing.js +1 -1
- package/lib/cjs/file.js +76 -50
- package/lib/cjs/func.js +1 -1
- package/lib/cjs/index.js +1 -1
- package/lib/cjs/isEqual.js +1 -1
- package/lib/cjs/math.js +1 -1
- package/lib/cjs/number.js +10 -4
- package/lib/cjs/object.js +1 -1
- package/lib/cjs/path.js +1 -1
- package/lib/cjs/qs.js +1 -1
- package/lib/cjs/random.js +1 -1
- package/lib/cjs/string.js +1 -1
- package/lib/cjs/tooltip.js +25 -18
- package/lib/cjs/tree.js +1 -1
- package/lib/cjs/type.js +1 -1
- package/lib/cjs/unique.js +1 -1
- package/lib/cjs/url.js +1 -1
- package/lib/cjs/validator.js +1 -1
- package/lib/cjs/variable.js +1 -1
- package/lib/cjs/watermark.js +20 -19
- package/lib/cjs/we-decode.js +1 -1
- package/lib/es/array.js +18 -1
- package/lib/es/async.js +1 -1
- package/lib/es/base64.js +1 -1
- package/lib/es/clipboard.js +1 -1
- package/lib/es/cloneDeep.js +1 -1
- package/lib/es/cookie.js +1 -1
- package/lib/es/date.js +1 -1
- package/lib/es/dom.js +11 -7
- package/lib/es/download.js +1 -1
- package/lib/es/easing.js +1 -1
- package/lib/es/file.js +76 -50
- package/lib/es/func.js +1 -1
- package/lib/es/index.js +1 -1
- package/lib/es/isEqual.js +1 -1
- package/lib/es/math.js +1 -1
- package/lib/es/number.js +10 -4
- package/lib/es/object.js +1 -1
- package/lib/es/path.js +1 -1
- package/lib/es/qs.js +1 -1
- package/lib/es/random.js +1 -1
- package/lib/es/string.js +1 -1
- package/lib/es/tooltip.js +25 -18
- package/lib/es/tree.js +1 -1
- package/lib/es/type.js +1 -1
- package/lib/es/unique.js +1 -1
- package/lib/es/url.js +1 -1
- package/lib/es/validator.js +1 -1
- package/lib/es/variable.js +1 -1
- package/lib/es/watermark.js +20 -19
- package/lib/es/we-decode.js +1 -1
- package/lib/index.d.ts +50 -26
- package/lib/umd/index.js +151 -94
- package/package.json +2 -1
package/lib/index.d.ts
CHANGED
|
@@ -106,6 +106,23 @@ declare function arrayEach<V>(array: ArrayLike<V>, iterator: (val: V, idx: numbe
|
|
|
106
106
|
* @param {ArrayLike<V>} array 数组
|
|
107
107
|
* @param {(val: V, idx: number) => Promise<any>} iterator 支持Promise类型的回调函数
|
|
108
108
|
* @param {boolean} reverse 是否反向遍历
|
|
109
|
+
* @example
|
|
110
|
+
* 使用范例如下:
|
|
111
|
+
* const start = async () => {
|
|
112
|
+
* await arrayEachAsync(result, async (item) => {
|
|
113
|
+
* await request(item);
|
|
114
|
+
* count++;
|
|
115
|
+
* })
|
|
116
|
+
* console.log('发送次数', count);
|
|
117
|
+
* }
|
|
118
|
+
|
|
119
|
+
* for await...of 使用范例如下
|
|
120
|
+
* const loadImages = async (images) => {
|
|
121
|
+
* for await (const item of images) {
|
|
122
|
+
* await request(item);
|
|
123
|
+
* count++;
|
|
124
|
+
* }
|
|
125
|
+
* }
|
|
109
126
|
*/
|
|
110
127
|
declare function arrayEachAsync<V>(array: ArrayLike<V>, iterator: (val: V, idx: number) => Promise<any> | any, reverse?: boolean): Promise<void>;
|
|
111
128
|
/**
|
|
@@ -285,10 +302,10 @@ declare function getComputedCssVal(el: HTMLElement, property: string, reNumber?:
|
|
|
285
302
|
* 字符串的像素宽度
|
|
286
303
|
* @param {string} str 目标字符串
|
|
287
304
|
* @param {number} fontSize 字符串字体大小
|
|
288
|
-
* @param {boolean}
|
|
305
|
+
* @param {boolean} isRemove 计算后是否移除创建的dom元素
|
|
289
306
|
* @returns {*}
|
|
290
307
|
*/
|
|
291
|
-
declare function getStrWidthPx(str: string, fontSize?: number,
|
|
308
|
+
declare function getStrWidthPx(str: string, fontSize?: number, isRemove?: boolean): number;
|
|
292
309
|
|
|
293
310
|
interface Params<T = string | number> {
|
|
294
311
|
[key: string]: T | Array<T>;
|
|
@@ -589,30 +606,31 @@ interface ICompressOptions {
|
|
|
589
606
|
}
|
|
590
607
|
/**
|
|
591
608
|
* Web端:等比例压缩图片批量处理 (size小于200KB,不压缩)
|
|
592
|
-
*
|
|
593
|
-
* @param {
|
|
609
|
+
*
|
|
610
|
+
* @param {File | FileList} file 图片或图片数组
|
|
611
|
+
* @param {ICompressOptions} options 压缩图片配置项,default: {quality:0.52,mime:'image/jpeg'}
|
|
594
612
|
* @returns {Promise<object> | undefined}
|
|
595
613
|
*/
|
|
596
|
-
declare function compressImg(file: File | FileList, options
|
|
614
|
+
declare function compressImg(file: File | FileList, options?: ICompressOptions): Promise<object> | undefined;
|
|
597
615
|
|
|
598
616
|
interface ICanvasWM {
|
|
599
|
-
|
|
600
|
-
width
|
|
601
|
-
height
|
|
602
|
-
textAlign
|
|
603
|
-
textBaseline
|
|
604
|
-
font
|
|
605
|
-
fillStyle
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
617
|
+
rootContainer?: HTMLElement | string;
|
|
618
|
+
width?: string;
|
|
619
|
+
height?: string;
|
|
620
|
+
textAlign?: CanvasTextAlign;
|
|
621
|
+
textBaseline?: CanvasTextBaseline;
|
|
622
|
+
font?: string;
|
|
623
|
+
fillStyle?: string;
|
|
624
|
+
rotate?: number;
|
|
625
|
+
zIndex?: number;
|
|
626
|
+
watermarkId?: string;
|
|
609
627
|
}
|
|
610
628
|
/**
|
|
611
629
|
* canvas 实现 水印, 具备防删除功能
|
|
612
630
|
* @param {ICanvasWM} canvasWM
|
|
613
631
|
* @example genCanvasWM({ content: 'QQMusicFE' })
|
|
614
632
|
*/
|
|
615
|
-
declare function genCanvasWM(canvasWM
|
|
633
|
+
declare function genCanvasWM(content?: string, canvasWM?: ICanvasWM): void;
|
|
616
634
|
|
|
617
635
|
interface DebounceFunc<F extends AnyFunc> {
|
|
618
636
|
(...args: Parameters<F>): void;
|
|
@@ -715,6 +733,7 @@ interface IHumanFileSizeOptions {
|
|
|
715
733
|
decimals?: number;
|
|
716
734
|
si?: boolean;
|
|
717
735
|
separator?: string;
|
|
736
|
+
baseUnit?: string;
|
|
718
737
|
maxUnit?: string;
|
|
719
738
|
}
|
|
720
739
|
/**
|
|
@@ -728,7 +747,7 @@ interface IHumanFileSizeOptions {
|
|
|
728
747
|
* ['Byte', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
|
|
729
748
|
* @returns
|
|
730
749
|
*/
|
|
731
|
-
declare function humanFileSize(num: number | string, options
|
|
750
|
+
declare function humanFileSize(num: number | string, options?: IHumanFileSizeOptions): string;
|
|
732
751
|
/**
|
|
733
752
|
* 将数字格式化成千位分隔符显示的字符串
|
|
734
753
|
* @param {number|string} num 数字
|
|
@@ -759,30 +778,35 @@ interface UniqueString {
|
|
|
759
778
|
declare const uniqueString: UniqueString;
|
|
760
779
|
|
|
761
780
|
/**
|
|
762
|
-
*
|
|
781
|
+
* 自定义的 tooltip, 支持鼠标移动动悬浮提示
|
|
763
782
|
* @Desc 自定义的tooltip方法, 支持拖动悬浮提示
|
|
764
783
|
* Created by chendeqiao on 2017/5/8.
|
|
765
784
|
* @example
|
|
766
|
-
* <span onmouseleave="handleMouseLeave('#root')"
|
|
767
|
-
*
|
|
785
|
+
* <span onmouseleave="handleMouseLeave('#root')"
|
|
786
|
+
* onmousemove="handleMouseEnter({rootContainer: '#root', title: 'title content', event: event})"
|
|
787
|
+
* onmouseenter="handleMouseEnter({rootContainer:'#root', title: 'title content', event: event})">
|
|
788
|
+
* title content
|
|
789
|
+
* </span>
|
|
768
790
|
*/
|
|
769
791
|
interface ITooltipParams {
|
|
770
|
-
|
|
792
|
+
rootContainer: HTMLElement | string;
|
|
771
793
|
title: string;
|
|
772
|
-
event: PointerEvent;
|
|
794
|
+
event: PointerEvent | MouseEvent;
|
|
795
|
+
bgColor?: string;
|
|
796
|
+
color?: string;
|
|
773
797
|
}
|
|
774
798
|
/**
|
|
775
799
|
* 自定义title提示功能的mouseenter事件句柄
|
|
776
|
-
* @param {ITooltipParams}
|
|
800
|
+
* @param {ITooltipParams} param
|
|
777
801
|
* @returns {*}
|
|
778
802
|
*/
|
|
779
|
-
declare function handleMouseEnter({
|
|
803
|
+
declare function handleMouseEnter({ rootContainer, title, event, bgColor, color }: ITooltipParams): void;
|
|
780
804
|
/**
|
|
781
805
|
* 移除提示文案dom的事件句柄
|
|
782
|
-
* @param {string}
|
|
806
|
+
* @param {string} rootContainer
|
|
783
807
|
* @returns {*}
|
|
784
808
|
*/
|
|
785
|
-
declare function handleMouseLeave(
|
|
809
|
+
declare function handleMouseLeave(rootContainer?: HTMLElement | string): void;
|
|
786
810
|
declare const tooltipEvent: {
|
|
787
811
|
handleMouseEnter: typeof handleMouseEnter;
|
|
788
812
|
handleMouseLeave: typeof handleMouseLeave;
|
package/lib/umd/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
2
|
+
* sculp-js v1.10.1
|
|
3
3
|
* (c) 2023-present chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -45,6 +45,23 @@
|
|
|
45
45
|
* @param {ArrayLike<V>} array 数组
|
|
46
46
|
* @param {(val: V, idx: number) => Promise<any>} iterator 支持Promise类型的回调函数
|
|
47
47
|
* @param {boolean} reverse 是否反向遍历
|
|
48
|
+
* @example
|
|
49
|
+
* 使用范例如下:
|
|
50
|
+
* const start = async () => {
|
|
51
|
+
* await arrayEachAsync(result, async (item) => {
|
|
52
|
+
* await request(item);
|
|
53
|
+
* count++;
|
|
54
|
+
* })
|
|
55
|
+
* console.log('发送次数', count);
|
|
56
|
+
* }
|
|
57
|
+
|
|
58
|
+
* for await...of 使用范例如下
|
|
59
|
+
* const loadImages = async (images) => {
|
|
60
|
+
* for await (const item of images) {
|
|
61
|
+
* await request(item);
|
|
62
|
+
* count++;
|
|
63
|
+
* }
|
|
64
|
+
* }
|
|
48
65
|
*/
|
|
49
66
|
async function arrayEachAsync(array, iterator, reverse = false) {
|
|
50
67
|
if (reverse) {
|
|
@@ -964,28 +981,32 @@
|
|
|
964
981
|
* 字符串的像素宽度
|
|
965
982
|
* @param {string} str 目标字符串
|
|
966
983
|
* @param {number} fontSize 字符串字体大小
|
|
967
|
-
* @param {boolean}
|
|
984
|
+
* @param {boolean} isRemove 计算后是否移除创建的dom元素
|
|
968
985
|
* @returns {*}
|
|
969
986
|
*/
|
|
970
|
-
function getStrWidthPx(str, fontSize = 14,
|
|
987
|
+
function getStrWidthPx(str, fontSize = 14, isRemove = true) {
|
|
971
988
|
let strWidth = 0;
|
|
972
989
|
console.assert(isString(str), `${str} 不是有效的字符串`);
|
|
973
990
|
if (isString(str) && str.length > 0) {
|
|
974
|
-
|
|
991
|
+
const id = 'getStrWidth1494304949567';
|
|
992
|
+
let getEle = document.querySelector(`#${id}`);
|
|
975
993
|
if (!getEle) {
|
|
976
994
|
const _ele = document.createElement('span');
|
|
977
|
-
_ele.id =
|
|
995
|
+
_ele.id = id;
|
|
978
996
|
_ele.style.fontSize = fontSize + 'px';
|
|
979
997
|
_ele.style.whiteSpace = 'nowrap';
|
|
980
998
|
_ele.style.visibility = 'hidden';
|
|
999
|
+
_ele.style.position = 'absolute';
|
|
1000
|
+
_ele.style.top = '-9999px';
|
|
1001
|
+
_ele.style.left = '-9999px';
|
|
981
1002
|
_ele.textContent = str;
|
|
982
1003
|
document.body.appendChild(_ele);
|
|
983
1004
|
getEle = _ele;
|
|
984
1005
|
}
|
|
985
1006
|
getEle.textContent = str;
|
|
986
1007
|
strWidth = getEle.offsetWidth;
|
|
987
|
-
if (
|
|
988
|
-
|
|
1008
|
+
if (isRemove) {
|
|
1009
|
+
getEle.remove();
|
|
989
1010
|
}
|
|
990
1011
|
}
|
|
991
1012
|
return strWidth;
|
|
@@ -1481,16 +1502,73 @@
|
|
|
1481
1502
|
};
|
|
1482
1503
|
return inputObj;
|
|
1483
1504
|
}
|
|
1505
|
+
/**
|
|
1506
|
+
* 计算图片压缩后的尺寸
|
|
1507
|
+
*
|
|
1508
|
+
* @param {number} maxWidth
|
|
1509
|
+
* @param {number} maxHeight
|
|
1510
|
+
* @param {number} originWidth
|
|
1511
|
+
* @param {number} originHeight
|
|
1512
|
+
* @returns {*}
|
|
1513
|
+
*/
|
|
1514
|
+
function calculateSize({ maxWidth, maxHeight, originWidth, originHeight }) {
|
|
1515
|
+
let width = originWidth, height = originHeight;
|
|
1516
|
+
// 图片尺寸超过限制
|
|
1517
|
+
if (originWidth > maxWidth || originHeight > maxHeight) {
|
|
1518
|
+
if (originWidth / originHeight > maxWidth / maxHeight) {
|
|
1519
|
+
// 更宽,按照宽度限定尺寸
|
|
1520
|
+
width = maxWidth;
|
|
1521
|
+
height = Math.round(maxWidth * (originHeight / originWidth));
|
|
1522
|
+
}
|
|
1523
|
+
else {
|
|
1524
|
+
height = maxHeight;
|
|
1525
|
+
width = Math.round(maxHeight * (originWidth / originHeight));
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
return { width, height };
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* 根据原始图片的不同尺寸计算等比例缩放后的宽高尺寸
|
|
1532
|
+
*
|
|
1533
|
+
* @param {number} sizeKB
|
|
1534
|
+
* @param {number} originWidth
|
|
1535
|
+
* @param {number} originHeight
|
|
1536
|
+
* @returns {*}
|
|
1537
|
+
*/
|
|
1538
|
+
function scalingByAspectRatio({ sizeKB, originWidth, originHeight }) {
|
|
1539
|
+
let targetWidth = originWidth, targetHeight = originHeight;
|
|
1540
|
+
if (1 * 1024 <= sizeKB && sizeKB < 10 * 1024) {
|
|
1541
|
+
// [1MB, 10MB)
|
|
1542
|
+
const maxWidth = 1600, maxHeight = 1600;
|
|
1543
|
+
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
1544
|
+
targetWidth = width;
|
|
1545
|
+
targetHeight = height;
|
|
1546
|
+
}
|
|
1547
|
+
else if (10 * 1024 <= sizeKB) {
|
|
1548
|
+
// [10MB, Infinity)
|
|
1549
|
+
const maxWidth = originWidth > 15000 ? 8192 : originWidth > 10000 ? 4096 : 2000, maxHeight = originHeight > 15000 ? 8192 : originHeight > 10000 ? 4096 : 2000;
|
|
1550
|
+
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
1551
|
+
targetWidth = width;
|
|
1552
|
+
targetHeight = height;
|
|
1553
|
+
}
|
|
1554
|
+
return { width: targetWidth, height: targetHeight };
|
|
1555
|
+
}
|
|
1484
1556
|
/**
|
|
1485
1557
|
* Web端:等比例压缩图片批量处理 (size小于200KB,不压缩)
|
|
1486
|
-
*
|
|
1487
|
-
* @param {
|
|
1558
|
+
*
|
|
1559
|
+
* @param {File | FileList} file 图片或图片数组
|
|
1560
|
+
* @param {ICompressOptions} options 压缩图片配置项,default: {quality:0.52,mime:'image/jpeg'}
|
|
1488
1561
|
* @returns {Promise<object> | undefined}
|
|
1489
1562
|
*/
|
|
1490
|
-
function compressImg(file, options) {
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1563
|
+
function compressImg(file, options = { quality: 0.52, mime: 'image/jpeg' }) {
|
|
1564
|
+
if (!(file instanceof File || file instanceof FileList)) {
|
|
1565
|
+
throw new Error(`${file} require be File or FileList`);
|
|
1566
|
+
}
|
|
1567
|
+
else if (!supportCanvas()) {
|
|
1568
|
+
throw new Error(`Current runtime environment not support Canvas`);
|
|
1569
|
+
}
|
|
1570
|
+
const { quality = 0.52, mime = 'image/jpeg' } = isObject(options) ? options : {};
|
|
1571
|
+
let targetQuality = quality;
|
|
1494
1572
|
if (file instanceof File) {
|
|
1495
1573
|
const sizeKB = +parseInt((file.size / 1024).toFixed(2));
|
|
1496
1574
|
if (sizeKB < 1 * 1024) {
|
|
@@ -1499,8 +1577,11 @@
|
|
|
1499
1577
|
else if (sizeKB >= 1 * 1024 && sizeKB < 5 * 1024) {
|
|
1500
1578
|
targetQuality = 0.62;
|
|
1501
1579
|
}
|
|
1502
|
-
else if (sizeKB >= 5 * 1024) {
|
|
1503
|
-
targetQuality = 0.
|
|
1580
|
+
else if (sizeKB >= 5 * 1024 && sizeKB < 10 * 1024) {
|
|
1581
|
+
targetQuality = 0.75;
|
|
1582
|
+
}
|
|
1583
|
+
else if (sizeKB >= 10 * 1024) {
|
|
1584
|
+
targetQuality = 0.92;
|
|
1504
1585
|
}
|
|
1505
1586
|
}
|
|
1506
1587
|
if (options.quality) {
|
|
@@ -1525,49 +1606,14 @@
|
|
|
1525
1606
|
image.onload = () => {
|
|
1526
1607
|
const canvas = document.createElement('canvas'); // 创建 canvas 元素
|
|
1527
1608
|
const context = canvas.getContext('2d');
|
|
1528
|
-
let targetWidth = image.width;
|
|
1529
|
-
let targetHeight = image.height;
|
|
1530
1609
|
const originWidth = image.width;
|
|
1531
1610
|
const originHeight = image.height;
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
if (originWidth / originHeight > maxWidth / maxHeight) {
|
|
1539
|
-
// 更宽,按照宽度限定尺寸
|
|
1540
|
-
targetWidth = maxWidth;
|
|
1541
|
-
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
|
|
1542
|
-
}
|
|
1543
|
-
else {
|
|
1544
|
-
targetHeight = maxHeight;
|
|
1545
|
-
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
if (10 * 1024 <= sizeKB && sizeKB <= 20 * 1024) {
|
|
1550
|
-
const maxWidth = 1400, maxHeight = 1400;
|
|
1551
|
-
targetWidth = originWidth;
|
|
1552
|
-
targetHeight = originHeight;
|
|
1553
|
-
// 图片尺寸超过的限制
|
|
1554
|
-
if (originWidth > maxWidth || originHeight > maxHeight) {
|
|
1555
|
-
if (originWidth / originHeight > maxWidth / maxHeight) {
|
|
1556
|
-
// 更宽,按照宽度限定尺寸
|
|
1557
|
-
targetWidth = maxWidth;
|
|
1558
|
-
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
|
|
1559
|
-
}
|
|
1560
|
-
else {
|
|
1561
|
-
targetHeight = maxHeight;
|
|
1562
|
-
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
canvas.width = targetWidth;
|
|
1567
|
-
canvas.height = targetHeight;
|
|
1568
|
-
context.clearRect(0, 0, targetWidth, targetHeight);
|
|
1569
|
-
context.drawImage(image, 0, 0, targetWidth, targetHeight); // 绘制 canvas
|
|
1570
|
-
const canvasURL = canvas.toDataURL(options.mime, targetQuality);
|
|
1611
|
+
const { width, height } = scalingByAspectRatio({ sizeKB, originWidth, originHeight });
|
|
1612
|
+
canvas.width = width;
|
|
1613
|
+
canvas.height = height;
|
|
1614
|
+
context.clearRect(0, 0, width, height);
|
|
1615
|
+
context.drawImage(image, 0, 0, width, height); // 绘制 canvas
|
|
1616
|
+
const canvasURL = canvas.toDataURL(mime, targetQuality);
|
|
1571
1617
|
const buffer = weAtob(canvasURL.split(',')[1]);
|
|
1572
1618
|
let length = buffer.length;
|
|
1573
1619
|
const bufferArray = new Uint8Array(new ArrayBuffer(length));
|
|
@@ -1606,15 +1652,14 @@
|
|
|
1606
1652
|
* @param {ICanvasWM} canvasWM
|
|
1607
1653
|
* @example genCanvasWM({ content: 'QQMusicFE' })
|
|
1608
1654
|
*/
|
|
1609
|
-
function genCanvasWM(canvasWM) {
|
|
1610
|
-
const {
|
|
1655
|
+
function genCanvasWM(content = '请勿外传', canvasWM) {
|
|
1656
|
+
const { rootContainer = document.body, width = '300px', height = '150px', textAlign = 'center', textBaseline = 'middle', font = '20px PingFangSC-Medium,PingFang SC',
|
|
1611
1657
|
// fontWeight = 500,
|
|
1612
|
-
fillStyle = 'rgba(189, 177, 167, .3)',
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
const args = canvasWM;
|
|
1658
|
+
fillStyle = 'rgba(189, 177, 167, .3)', rotate = -20, zIndex = 2147483647, watermarkId = '__wm' } = isNullOrUnDef(canvasWM) ? {} : canvasWM;
|
|
1659
|
+
const container = isString(rootContainer) ? document.querySelector(rootContainer) : rootContainer;
|
|
1660
|
+
if (!container) {
|
|
1661
|
+
throw new Error(`${rootContainer} is not valid Html Element or element selector`);
|
|
1662
|
+
}
|
|
1618
1663
|
const canvas = document.createElement('canvas');
|
|
1619
1664
|
canvas.setAttribute('width', width);
|
|
1620
1665
|
canvas.setAttribute('height', height);
|
|
@@ -1627,36 +1672,36 @@
|
|
|
1627
1672
|
ctx.rotate((Math.PI / 180) * rotate);
|
|
1628
1673
|
ctx.fillText(content, parseFloat(width) / 4, parseFloat(height) / 2);
|
|
1629
1674
|
const base64Url = canvas.toDataURL();
|
|
1630
|
-
const __wm = document.querySelector(
|
|
1675
|
+
const __wm = document.querySelector(`#${watermarkId}`);
|
|
1631
1676
|
const watermarkDiv = __wm || document.createElement('div');
|
|
1632
1677
|
const styleStr = `opacity: 1 !important; display: block !important; visibility: visible !important; position:absolute; left:0; top:0; width:100%; height:100%; z-index:${zIndex}; pointer-events:none; background-repeat:repeat; background-image:url('${base64Url}')`;
|
|
1633
1678
|
watermarkDiv.setAttribute('style', styleStr);
|
|
1634
|
-
watermarkDiv.
|
|
1679
|
+
watermarkDiv.setAttribute('id', watermarkId);
|
|
1635
1680
|
watermarkDiv.classList.add('nav-height');
|
|
1636
1681
|
if (!__wm) {
|
|
1637
1682
|
container.style.position = 'relative';
|
|
1638
1683
|
container.appendChild(watermarkDiv);
|
|
1639
1684
|
}
|
|
1640
1685
|
const getMutableStyle = (ele) => {
|
|
1641
|
-
const
|
|
1686
|
+
const computedStyle = getComputedStyle(ele);
|
|
1642
1687
|
return {
|
|
1643
|
-
opacity:
|
|
1644
|
-
zIndex:
|
|
1645
|
-
display:
|
|
1646
|
-
visibility:
|
|
1688
|
+
opacity: computedStyle.getPropertyValue('opacity'),
|
|
1689
|
+
zIndex: computedStyle.getPropertyValue('z-index'),
|
|
1690
|
+
display: computedStyle.getPropertyValue('display'),
|
|
1691
|
+
visibility: computedStyle.getPropertyValue('visibility')
|
|
1647
1692
|
};
|
|
1648
1693
|
};
|
|
1649
1694
|
//@ts-ignore
|
|
1650
1695
|
const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
|
|
1651
1696
|
if (MutationObserver) {
|
|
1652
1697
|
let mo = new MutationObserver(function () {
|
|
1653
|
-
const __wm = document.querySelector(
|
|
1698
|
+
const __wm = document.querySelector(`#${watermarkId}`); // 只在__wm元素变动才重新调用 __canvasWM
|
|
1654
1699
|
if (!__wm) {
|
|
1655
1700
|
// 避免一直触发
|
|
1656
1701
|
// console.log('regenerate watermark by delete::')
|
|
1657
1702
|
mo.disconnect();
|
|
1658
1703
|
mo = null;
|
|
1659
|
-
genCanvasWM(
|
|
1704
|
+
genCanvasWM(content, canvasWM);
|
|
1660
1705
|
}
|
|
1661
1706
|
else {
|
|
1662
1707
|
const { opacity, zIndex, display, visibility } = getMutableStyle(__wm);
|
|
@@ -1668,7 +1713,7 @@
|
|
|
1668
1713
|
mo.disconnect();
|
|
1669
1714
|
mo = null;
|
|
1670
1715
|
container.removeChild(__wm);
|
|
1671
|
-
genCanvasWM(
|
|
1716
|
+
genCanvasWM(content, canvasWM);
|
|
1672
1717
|
}
|
|
1673
1718
|
}
|
|
1674
1719
|
});
|
|
@@ -1921,11 +1966,17 @@
|
|
|
1921
1966
|
* ['Byte', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
|
|
1922
1967
|
* @returns
|
|
1923
1968
|
*/
|
|
1924
|
-
function humanFileSize(num, options) {
|
|
1925
|
-
const { decimals = 0, si = false, separator = ' ', maxUnit } = options;
|
|
1926
|
-
|
|
1969
|
+
function humanFileSize(num, options = { decimals: 0, si: false, separator: ' ' }) {
|
|
1970
|
+
const { decimals = 0, si = false, separator = ' ', baseUnit, maxUnit } = options;
|
|
1971
|
+
let units = si
|
|
1927
1972
|
? ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
|
1928
1973
|
: ['Byte', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
|
1974
|
+
if (!isNullOrUnDef(baseUnit)) {
|
|
1975
|
+
const targetIndex = units.findIndex(el => el === baseUnit);
|
|
1976
|
+
if (targetIndex !== -1) {
|
|
1977
|
+
units = units.slice(targetIndex);
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1929
1980
|
if (!isNullOrUnDef(maxUnit)) {
|
|
1930
1981
|
const targetIndex = units.findIndex(el => el === maxUnit);
|
|
1931
1982
|
if (targetIndex !== -1) {
|
|
@@ -2023,49 +2074,55 @@
|
|
|
2023
2074
|
};
|
|
2024
2075
|
|
|
2025
2076
|
/**
|
|
2026
|
-
*
|
|
2077
|
+
* 自定义的 tooltip, 支持鼠标移动动悬浮提示
|
|
2027
2078
|
* @Desc 自定义的tooltip方法, 支持拖动悬浮提示
|
|
2028
2079
|
* Created by chendeqiao on 2017/5/8.
|
|
2029
2080
|
* @example
|
|
2030
|
-
* <span onmouseleave="handleMouseLeave('#root')"
|
|
2031
|
-
*
|
|
2081
|
+
* <span onmouseleave="handleMouseLeave('#root')"
|
|
2082
|
+
* onmousemove="handleMouseEnter({rootContainer: '#root', title: 'title content', event: event})"
|
|
2083
|
+
* onmouseenter="handleMouseEnter({rootContainer:'#root', title: 'title content', event: event})">
|
|
2084
|
+
* title content
|
|
2085
|
+
* </span>
|
|
2032
2086
|
*/
|
|
2033
2087
|
/**
|
|
2034
2088
|
* 自定义title提示功能的mouseenter事件句柄
|
|
2035
|
-
* @param {ITooltipParams}
|
|
2089
|
+
* @param {ITooltipParams} param
|
|
2036
2090
|
* @returns {*}
|
|
2037
2091
|
*/
|
|
2038
|
-
function handleMouseEnter({
|
|
2092
|
+
function handleMouseEnter({ rootContainer = '#root', title, event, bgColor = '#000', color = '#fff' }) {
|
|
2039
2093
|
try {
|
|
2040
|
-
const $rootEl = document.querySelector(
|
|
2041
|
-
|
|
2094
|
+
const $rootEl = isString(rootContainer) ? document.querySelector(rootContainer) : rootContainer;
|
|
2095
|
+
if (!$rootEl) {
|
|
2096
|
+
throw new Error(`${rootContainer} is not valid Html Element or element selector`);
|
|
2097
|
+
}
|
|
2042
2098
|
let $customTitle = null;
|
|
2099
|
+
const styleId = 'style-tooltip-inner1494304949567';
|
|
2043
2100
|
// 动态创建class样式,并加入到head中
|
|
2044
|
-
if (!document.querySelector(
|
|
2101
|
+
if (!document.querySelector(`#${styleId}`)) {
|
|
2045
2102
|
const tooltipWrapperClass = document.createElement('style');
|
|
2046
2103
|
tooltipWrapperClass.type = 'text/css';
|
|
2104
|
+
tooltipWrapperClass.id = styleId;
|
|
2047
2105
|
tooltipWrapperClass.innerHTML = `
|
|
2048
2106
|
.tooltip-inner1494304949567 {
|
|
2049
2107
|
max-width: 250px;
|
|
2050
2108
|
padding: 3px 8px;
|
|
2051
|
-
color:
|
|
2109
|
+
color: ${color};
|
|
2052
2110
|
text-decoration: none;
|
|
2053
2111
|
border-radius: 4px;
|
|
2054
2112
|
text-align: left;
|
|
2113
|
+
background-color: ${bgColor};
|
|
2055
2114
|
}
|
|
2056
2115
|
`;
|
|
2057
2116
|
document.querySelector('head').appendChild(tooltipWrapperClass);
|
|
2058
2117
|
}
|
|
2059
|
-
|
|
2060
|
-
|
|
2118
|
+
$customTitle = document.querySelector('#customTitle1494304949567');
|
|
2119
|
+
if ($customTitle) {
|
|
2061
2120
|
mouseenter($customTitle, title, event);
|
|
2062
2121
|
}
|
|
2063
2122
|
else {
|
|
2064
2123
|
const $contentContainer = document.createElement('div');
|
|
2065
|
-
$contentContainer.className = 'customTitle';
|
|
2066
2124
|
$contentContainer.id = 'customTitle1494304949567';
|
|
2067
|
-
$contentContainer.
|
|
2068
|
-
$contentContainer.style.cssText = 'z-index: 99999999; visibility: hidden;';
|
|
2125
|
+
$contentContainer.style.cssText = 'z-index: 99999999; visibility: hidden; position: absolute;';
|
|
2069
2126
|
$contentContainer.innerHTML =
|
|
2070
2127
|
'<div class="tooltip-inner1494304949567" style="word-wrap: break-word; max-width: 44px;">皮肤</div>';
|
|
2071
2128
|
$rootEl.appendChild($contentContainer);
|
|
@@ -2118,11 +2175,11 @@
|
|
|
2118
2175
|
}
|
|
2119
2176
|
/**
|
|
2120
2177
|
* 移除提示文案dom的事件句柄
|
|
2121
|
-
* @param {string}
|
|
2178
|
+
* @param {string} rootContainer
|
|
2122
2179
|
* @returns {*}
|
|
2123
2180
|
*/
|
|
2124
|
-
function handleMouseLeave(
|
|
2125
|
-
const rootEl = document.querySelector(
|
|
2181
|
+
function handleMouseLeave(rootContainer = '#root') {
|
|
2182
|
+
const rootEl = isString(rootContainer) ? document.querySelector(rootContainer) : rootContainer, titleEl = document.querySelector('#customTitle1494304949567');
|
|
2126
2183
|
if (rootEl && titleEl) {
|
|
2127
2184
|
rootEl.removeChild(titleEl);
|
|
2128
2185
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sculp-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"packageManager": "npm@8.19.2",
|
|
5
5
|
"description": "js utils library, includes function library、class library",
|
|
6
6
|
"scripts": {
|
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
"eslint-plugin-standard": "^5.0.0",
|
|
80
80
|
"husky": "^8.0.3",
|
|
81
81
|
"jest": "^29.7.0",
|
|
82
|
+
"jest-canvas-mock": "^2.5.2",
|
|
82
83
|
"jest-environment-jsdom": "^29.7.0",
|
|
83
84
|
"lint-staged": "^13.2.2",
|
|
84
85
|
"prettier": "^3.0.3",
|