@qy_better_lib/hooks 0.0.2

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.
Files changed (52) hide show
  1. package/dist/@qy_better_lib/hooks.min.js +1 -0
  2. package/lib/index.d.ts +6 -0
  3. package/lib/index.js +24 -0
  4. package/lib/use-emit/index.d.ts +14 -0
  5. package/lib/use-file/index.d.ts +12 -0
  6. package/lib/use-image/canvastoDataURL.d.ts +12 -0
  7. package/lib/use-image/canvastoDataURL.js +7 -0
  8. package/lib/use-image/canvastoFile.d.ts +12 -0
  9. package/lib/use-image/canvastoFile.js +9 -0
  10. package/lib/use-image/dataURLtoFile.d.ts +11 -0
  11. package/lib/use-image/dataURLtoFile.js +17 -0
  12. package/lib/use-image/dataURLtoImage.d.ts +7 -0
  13. package/lib/use-image/dataURLtoImage.js +9 -0
  14. package/lib/use-image/downloadFile.d.ts +7 -0
  15. package/lib/use-image/downloadFile.js +9 -0
  16. package/lib/use-image/filetoDataURL.d.ts +7 -0
  17. package/lib/use-image/filetoDataURL.js +12 -0
  18. package/lib/use-image/imagetoCanvas.d.ts +27 -0
  19. package/lib/use-image/imagetoCanvas.js +41 -0
  20. package/lib/use-image/index.d.ts +55 -0
  21. package/lib/use-image/index.js +74 -0
  22. package/lib/use-image/type.d.ts +25 -0
  23. package/lib/use-image/type.js +8 -0
  24. package/lib/use-image/urltoBlob.d.ts +8 -0
  25. package/lib/use-image/urltoBlob.js +6 -0
  26. package/lib/use-image/urltoImage.d.ts +7 -0
  27. package/lib/use-image/urltoImage.js +13 -0
  28. package/lib/use-print/index.d.ts +11 -0
  29. package/lib/use-waterMark/index.d.ts +17 -0
  30. package/lib/use-websocket/index.d.ts +15 -0
  31. package/package.json +50 -0
  32. package/src/index.ts +6 -0
  33. package/src/use-emit/index.ts +46 -0
  34. package/src/use-file/index.ts +39 -0
  35. package/src/use-image/canvastoDataURL.ts +21 -0
  36. package/src/use-image/canvastoFile.ts +20 -0
  37. package/src/use-image/dataURLtoFile.ts +29 -0
  38. package/src/use-image/dataURLtoImage.ts +17 -0
  39. package/src/use-image/downloadFile.ts +16 -0
  40. package/src/use-image/filetoDataURL.ts +13 -0
  41. package/src/use-image/imagetoCanvas.ts +107 -0
  42. package/src/use-image/index.ts +200 -0
  43. package/src/use-image/type.ts +31 -0
  44. package/src/use-image/urltoBlob.ts +10 -0
  45. package/src/use-image/urltoImage.ts +19 -0
  46. package/src/use-print/index.ts +128 -0
  47. package/src/use-waterMark/index.ts +101 -0
  48. package/src/use-websocket/index.ts +117 -0
  49. package/tsconfig.json +5 -0
  50. package/types/index.d.ts +1 -0
  51. package/types/json.d.ts +4 -0
  52. package/types/vue.shim.d.ts +5 -0
@@ -0,0 +1,39 @@
1
+ interface UseFile {
2
+ /**下载文件 */
3
+ downLoadFile: (filePath: string) => void;
4
+ /**批量下载文件 */
5
+ downLoadFiles: (list: Array<any>) => void;
6
+ }
7
+ /**
8
+ * 文件处理
9
+ * @returns
10
+ */
11
+ export default function useFile(): UseFile {
12
+ /**
13
+ * 下载文件
14
+ * @param filePath 文件路径
15
+ */
16
+ function downLoadFile(filePath: string): void {
17
+ window.open(filePath);
18
+ }
19
+
20
+ function downLoadFiles(fileList: any[]): void {
21
+ fileList.forEach((file) => {
22
+ // file.url && window.open(file.url, '_blank');
23
+ //通过模拟a标签点击事件下载文件
24
+ const link = document.createElement("a");
25
+ link.href = file.url;
26
+ link.target = "_blank";
27
+ link.setAttribute("download", file.name);
28
+ document.body.appendChild(link);
29
+ link.click();
30
+ document.body.removeChild(link);
31
+ });
32
+ }
33
+
34
+ return {
35
+ downLoadFile,
36
+ downLoadFiles,
37
+ };
38
+ }
39
+
@@ -0,0 +1,21 @@
1
+ import { EImageType, checkImageType } from "./type";
2
+
3
+ /**
4
+ * 将一个Canvas对象转变为一个dataURL字符串
5
+ * 该方法可以做压缩处理
6
+ *
7
+ * @param {canvas} canvas
8
+ * @param {number=} quality - 传入范围 0-1,表示图片压缩质量,默认0.92
9
+ * @param {string=} type - 确定转换后的图片类型,选项有 "image/png", "image/jpeg", "image/gif",默认"image/jpeg"
10
+ * @returns {Promise(string)} Promise含有一个dataURL字符串参数
11
+ */
12
+ export default async function canvastoDataURL(
13
+ canvas: HTMLCanvasElement,
14
+ quality: number = 0.92,
15
+ type: EImageType = EImageType.JPEG
16
+ ): Promise<string> {
17
+ if (!checkImageType(type)) {
18
+ type = EImageType.JPEG;
19
+ }
20
+ return canvas.toDataURL(type, quality);
21
+ }
@@ -0,0 +1,20 @@
1
+ import { EImageType } from "./type";
2
+
3
+ /**
4
+ * 将一个canvas对象转变为一个File(Blob)对象
5
+ * 该方法可以做压缩处理
6
+ *
7
+ * @param {canvas} canvas
8
+ * @param {number=} quality - 传入范围 0-1,表示图片压缩质量,默认0.92
9
+ * @param {string=} type - 确定转换后的图片类型,选项有 "image/png", "image/jpeg", "image/gif",默认"image/jpeg"
10
+ * @returns {Promise(Blob)}
11
+ */
12
+ export default function canvastoFile(
13
+ canvas: HTMLCanvasElement,
14
+ quality: number = 0.92,
15
+ type: EImageType = EImageType.JPEG
16
+ ): Promise<Blob> {
17
+ return new Promise((resolve) =>
18
+ canvas.toBlob((blob) => resolve(blob as Blob), type, quality)
19
+ );
20
+ }
@@ -0,0 +1,29 @@
1
+ import { EImageType, checkImageType } from "./type";
2
+
3
+ /**
4
+ * 将一个dataURL字符串转变为一个File(Blob)对象
5
+ * 转变时可以确定File对象的类型
6
+ *
7
+ * @param {string} dataURL
8
+ * @param {string=} type - 确定转换后的图片类型,选项有 "image/png", "image/jpeg", "image/gif"
9
+ * @returns {Promise(Blob)}
10
+ */
11
+ export default async function dataURLtoFile(
12
+ dataURL: string,
13
+ type: EImageType
14
+ ): Promise<Blob> {
15
+ const arr = dataURL.split(",");
16
+ let mime = arr[0].match(/:(.*?);/)?.[1];
17
+ const bstr = atob(arr[1]);
18
+ let n = bstr.length;
19
+ const u8arr = new Uint8Array(n);
20
+ while (n--) {
21
+ u8arr[n] = bstr.charCodeAt(n);
22
+ }
23
+ if (checkImageType(type)) {
24
+ mime = type;
25
+ }
26
+ return new Blob([u8arr], {
27
+ type: mime,
28
+ });
29
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 将dataURL字符串转变为image对象
3
+ *
4
+ * @param {srting} dataURL - dataURL字符串
5
+ * @returns {Promise(Image)}
6
+ */
7
+ export default function dataURLtoImage(
8
+ dataURL: string
9
+ ): Promise<HTMLImageElement> {
10
+ return new Promise((resolve, reject) => {
11
+ const img = new Image();
12
+ img.onload = () => resolve(img);
13
+ img.onerror = () =>
14
+ reject(new Error("dataURLtoImage(): dataURL is illegal"));
15
+ img.src = dataURL;
16
+ });
17
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 将图片下载到本地
3
+ *
4
+ * @param {Blob} file - 一个File(Blob)对象
5
+ * @param {string=} fileName - 下载后的文件名(可选参数,不传以时间戳命名文件)
6
+ */
7
+ export default function downloadFile(file: File, fileName: string): void {
8
+ const link = document.createElement("a");
9
+ link.href = window.URL.createObjectURL(file);
10
+ link.download = fileName || Date.now().toString(36);
11
+ document.body.appendChild(link);
12
+ const evt = document.createEvent("MouseEvents");
13
+ evt.initEvent("click", false, false);
14
+ link.dispatchEvent(evt);
15
+ document.body.removeChild(link);
16
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 将File(Blob)对象转变为一个dataURL字符串
3
+ *
4
+ * @param {Blob} file
5
+ * @returns {Promise(string)} Promise含有一个dataURL字符串参数
6
+ */
7
+ export default function filetoDataURL(file: Blob): Promise<string> {
8
+ return new Promise((resolve) => {
9
+ const reader = new FileReader();
10
+ reader.onloadend = (e) => resolve(e.target?.result as string);
11
+ reader.readAsDataURL(file);
12
+ });
13
+ }
@@ -0,0 +1,107 @@
1
+ import { Image2CanvasConfig } from "./type";
2
+
3
+ /**
4
+ * 将一个image对象转变为一个canvas对象
5
+ *
6
+ * @param {image} image
7
+ *
8
+ * @typedef {Object=} config - 转变为canvas时的一些参数配置
9
+ * @param {number} width - canvas图像的宽度,默认为image的宽度
10
+ * @param {number} height - canvas图像的高度,默认为image的高度
11
+ * @param {number} scale - 相对于image的缩放比例,范围0-10,默认不缩放;
12
+ * 设置config.scale后会覆盖config.width和config.height的设置;
13
+ * @param {number} orientation - 图片旋转参数,默认不旋转,参考如下:
14
+ * 参数 旋转方向
15
+ * 1 0°
16
+ * 2 水平翻转
17
+ * 3 180°
18
+ * 4 垂直翻转
19
+ * 5 顺时针90°+水平翻转
20
+ * 6 顺时针90°
21
+ * 7 顺时针90°+垂直翻转
22
+ * 8 逆时针90°
23
+ * @type {config}
24
+ *
25
+ * @returns {Promise(canvas)}
26
+ */
27
+ export default async function imagetoCanvas(
28
+ image: HTMLImageElement,
29
+ config: Image2CanvasConfig = {}
30
+ ): Promise<HTMLCanvasElement> {
31
+ const myConfig = { ...config };
32
+ const cvs = document.createElement("canvas");
33
+ const ctx = cvs.getContext("2d") as CanvasRenderingContext2D;
34
+ let height;
35
+ let width;
36
+ for (const i in myConfig) {
37
+ if (Object.prototype.hasOwnProperty.call(myConfig, i)) {
38
+ myConfig[i] = Number(myConfig[i]);
39
+ }
40
+ }
41
+ // 设置宽高
42
+ if (!myConfig.scale) {
43
+ width =
44
+ myConfig.width ||
45
+ ((myConfig.height || 0) * image.width) / image.height ||
46
+ image.width;
47
+ height =
48
+ myConfig.height ||
49
+ ((myConfig.width || 0) * image.height) / image.width ||
50
+ image.height;
51
+ } else {
52
+ // 缩放比例0-10,不在此范围则保持原来图像大小
53
+ const scale =
54
+ myConfig.scale > 0 && myConfig.scale < 10 ? myConfig.scale : 1;
55
+ width = image.width * scale;
56
+ height = image.height * scale;
57
+ }
58
+ // 当顺时针或者逆时针旋转90时,需要交换canvas的宽高
59
+ if ([5, 6, 7, 8].some((i) => i === myConfig.orientation)) {
60
+ cvs.height = width;
61
+ cvs.width = height;
62
+ } else {
63
+ cvs.height = height;
64
+ cvs.width = width;
65
+ }
66
+ // 设置方向
67
+ switch (myConfig.orientation) {
68
+ case 3:
69
+ ctx.rotate((180 * Math.PI) / 180);
70
+ ctx.drawImage(image, -cvs.width, -cvs.height, cvs.width, cvs.height);
71
+ break;
72
+ case 6:
73
+ ctx.rotate((90 * Math.PI) / 180);
74
+ ctx.drawImage(image, 0, -cvs.width, cvs.height, cvs.width);
75
+ break;
76
+ case 8:
77
+ ctx.rotate((270 * Math.PI) / 180);
78
+ ctx.drawImage(image, -cvs.height, 0, cvs.height, cvs.width);
79
+ break;
80
+ case 2:
81
+ ctx.translate(cvs.width, 0);
82
+ ctx.scale(-1, 1);
83
+ ctx.drawImage(image, 0, 0, cvs.width, cvs.height);
84
+ break;
85
+ case 4:
86
+ ctx.translate(cvs.width, 0);
87
+ ctx.scale(-1, 1);
88
+ ctx.rotate((180 * Math.PI) / 180);
89
+ ctx.drawImage(image, -cvs.width, -cvs.height, cvs.width, cvs.height);
90
+ break;
91
+ case 5:
92
+ ctx.translate(cvs.width, 0);
93
+ ctx.scale(-1, 1);
94
+ ctx.rotate((90 * Math.PI) / 180);
95
+ ctx.drawImage(image, 0, -cvs.width, cvs.height, cvs.width);
96
+ break;
97
+ case 7:
98
+ ctx.translate(cvs.width, 0);
99
+ ctx.scale(-1, 1);
100
+ ctx.rotate((270 * Math.PI) / 180);
101
+ ctx.drawImage(image, -cvs.height, 0, cvs.height, cvs.width);
102
+ break;
103
+ default:
104
+ ctx.drawImage(image, 0, 0, cvs.width, cvs.height);
105
+ }
106
+ return cvs;
107
+ }
@@ -0,0 +1,200 @@
1
+ import canvastoDataURL from "./canvastoDataURL";
2
+ import canvastoFile from "./canvastoFile";
3
+ import dataURLtoFile from "./dataURLtoFile";
4
+ import dataURLtoImage from "./dataURLtoImage";
5
+ import downloadFile from "./downloadFile";
6
+ import filetoDataURL from "./filetoDataURL";
7
+ import imagetoCanvas from "./imagetoCanvas";
8
+ import urltoBlob from "./urltoBlob";
9
+ import urltoImage from "./urltoImage";
10
+ import {
11
+ EImageType,
12
+ ICompressConfig,
13
+ checkImageType,
14
+ compressAccuratelyConfig,
15
+ } from "./type";
16
+
17
+ /**
18
+ * 压缩File(Blob)对象
19
+ * @param {Blob} file - 一个File(Blob)对象
20
+ * @param {(number|object)} config - 如果传入是number类型,传入范围 0-1,表示图片压缩质量,默认0.92;也可以传入object类型,以便更详细的配置
21
+ * @example
22
+ * imageConversion.compress(file,0.8)
23
+ *
24
+ * imageConversion.compress(file,{
25
+ * quality: 0.8, //图片压缩质量
26
+ * type:"image/png", //转换后的图片类型,选项有 "image/png", "image/jpeg", "image/gif"
27
+ * width: 300, //生成图片的宽度
28
+ * height:200, //生产图片的高度
29
+ * scale: 0.5, //相对于原始图片的缩放比率,设置config.scale后会覆盖config.width和config.height的设置;
30
+ * orientation:2, //图片旋转方向
31
+ * })
32
+ *
33
+ * @returns {Promise(Blob)}
34
+ */
35
+ async function compress(
36
+ file: File,
37
+ config: ICompressConfig = {}
38
+ ): Promise<Blob> {
39
+ if (!(file instanceof Blob)) {
40
+ throw new Error(
41
+ "compress(): First arg must be a Blob object or a File object."
42
+ );
43
+ }
44
+ if (typeof config !== "object") {
45
+ config = Object.assign({
46
+ quality: config,
47
+ });
48
+ }
49
+ config.quality = Number(config.quality);
50
+ if (Number.isNaN(config.quality)) {
51
+ return file;
52
+ }
53
+ const dataURL = await filetoDataURL(file);
54
+ let originalMime = dataURL.split(",")[0].match(/:(.*?);/)?.[1] as EImageType; // 原始图像图片类型
55
+ let mime = EImageType.JPEG; // 默认压缩类型
56
+ if (checkImageType(config.type as EImageType)) {
57
+ mime = config.type as EImageType;
58
+ originalMime = config.type as EImageType;
59
+ }
60
+ const image = await dataURLtoImage(dataURL);
61
+ const canvas = await imagetoCanvas(image, Object.assign({}, config));
62
+ const compressDataURL = await canvastoDataURL(canvas, config.quality, mime);
63
+ const compressFile = await dataURLtoFile(compressDataURL, originalMime);
64
+ if (compressFile.size > file.size) {
65
+ return file;
66
+ }
67
+ return compressFile;
68
+ }
69
+
70
+ /**
71
+ * 根据体积压缩File(Blob)对象
72
+ *
73
+ * @param {Blob} file - 一个File(Blob)对象
74
+ * @param {(number|object)} config - 如果传入是number类型,则指定压缩图片的体积,单位Kb;也可以传入object类型,以便更详细的配置
75
+ * @param {number} size - 指定压缩图片的体积,单位Kb
76
+ * @param {number} accuracy - 相对于指定压缩体积的精确度,范围0.8-0.99,默认0.95;
77
+ * 如果设置 图片体积1000Kb,精确度0.9,则压缩结果为900Kb-1100Kb的图片都算合格;
78
+ * @example
79
+ * imageConversion.compress(file,100) //压缩后图片大小为100kb
80
+ *
81
+ * imageConversion.compress(file,{
82
+ * size: 100, //图片压缩体积,单位Kb
83
+ * accuracy: 0.9, //图片压缩体积的精确度,默认0.95
84
+ * type:"image/png", //转换后的图片类型,选项有 "image/png", "image/jpeg", "image/gif"
85
+ * width: 300, //生成图片的宽度
86
+ * height: 200, //生产图片的高度
87
+ * scale: 0.5, //相对于原始图片的缩放比率,设置config.scale后会覆盖config.width和config.height的设置;
88
+ * orientation:2, //图片旋转方向
89
+ * })
90
+ *
91
+ * @returns {Promise(Blob)}
92
+ */
93
+ async function compressAccurately(
94
+ file: Blob,
95
+ config: compressAccuratelyConfig = {}
96
+ ): Promise<Blob> {
97
+ if (!(file instanceof Blob)) {
98
+ throw new Error(
99
+ "compressAccurately(): First arg must be a Blob object or a File object."
100
+ );
101
+ }
102
+ if (typeof config !== "object") {
103
+ config = Object.assign({
104
+ size: config,
105
+ });
106
+ }
107
+ // 如果指定体积不是数字或者数字字符串,则不做处理
108
+ config.size = Number(config.size);
109
+ if (Number.isNaN(config.size)) {
110
+ return file;
111
+ }
112
+ // 如果指定体积大于原文件体积,则不做处理;
113
+ if (config.size * 1024 > file.size) {
114
+ return file;
115
+ }
116
+ config.accuracy = Number(config.accuracy);
117
+ if (!config.accuracy || config.accuracy < 0.8 || config.accuracy > 0.99) {
118
+ config.accuracy = 0.95; // 默认精度0.95
119
+ }
120
+ const resultSize = {
121
+ max: config.size * (2 - config.accuracy) * 1024,
122
+ accurate: config.size * 1024,
123
+ min: config.size * config.accuracy * 1024,
124
+ };
125
+ const dataURL = await filetoDataURL(file);
126
+ let originalMime = dataURL.split(",")[0].match(/:(.*?);/)?.[1] as EImageType; // 原始图像图片类型
127
+ let mime = EImageType.JPEG;
128
+ if (checkImageType(config.type as EImageType)) {
129
+ mime = config.type as EImageType;
130
+ originalMime = config.type as EImageType;
131
+ }
132
+ const image = await dataURLtoImage(dataURL);
133
+ const canvas = await imagetoCanvas(image, Object.assign({}, config));
134
+ /**
135
+ * 经过测试发现,blob.size与dataURL.length的比值约等于0.75
136
+ * 这个比值可以同过dataURLtoFile这个方法来测试验证
137
+ * 这里为了提高性能,直接通过这个比值来计算出blob.size
138
+ */
139
+ const proportion = 0.75;
140
+ let imageQuality = 1;
141
+ let compressDataURL;
142
+ const tempDataURLs: string[] = new Array(2);
143
+ /**
144
+ * HTMLCanvasElement.toBlob()以及HTMLCanvasElement.toDataURL()压缩参数
145
+ * 的最小细粒度为0.01,而2的7次方为128,即只要循环7次,则会覆盖所有可能性
146
+ */
147
+ for (let x = 1; x <= 7; x++) {
148
+ compressDataURL = await canvastoDataURL(canvas, imageQuality, mime);
149
+ const CalculationSize = compressDataURL.length * proportion;
150
+ // 如果到循环第七次还没有达到精确度的值,那说明该图片不能达到到此精确度要求
151
+ // 这时候最后一次循环出来的dataURL可能不是最精确的,需要取其周边两个dataURL三者比较来选出最精确的;
152
+ if (x === 7) {
153
+ if (
154
+ resultSize.max < CalculationSize ||
155
+ resultSize.min > CalculationSize
156
+ ) {
157
+ compressDataURL = [compressDataURL, ...tempDataURLs]
158
+ .filter((i) => i) // 去除null
159
+ .sort(
160
+ (a, b) =>
161
+ Math.abs(a.length * proportion - resultSize.accurate) -
162
+ Math.abs(b.length * proportion - resultSize.accurate)
163
+ )[0];
164
+ }
165
+ break;
166
+ }
167
+ if (resultSize.max < CalculationSize) {
168
+ tempDataURLs[1] = compressDataURL;
169
+ imageQuality -= 0.5 ** (x + 1);
170
+ } else if (resultSize.min > CalculationSize) {
171
+ tempDataURLs[0] = compressDataURL;
172
+ imageQuality += 0.5 ** (x + 1);
173
+ } else {
174
+ break;
175
+ }
176
+ }
177
+ const compressFile = await dataURLtoFile(
178
+ compressDataURL as string,
179
+ originalMime
180
+ );
181
+ // 如果压缩后体积大于原文件体积,则返回源文件;
182
+ if (compressFile.size > file.size) {
183
+ return file;
184
+ }
185
+ return compressFile;
186
+ }
187
+
188
+ export {
189
+ canvastoDataURL,
190
+ canvastoFile,
191
+ dataURLtoFile,
192
+ dataURLtoImage,
193
+ downloadFile,
194
+ filetoDataURL,
195
+ imagetoCanvas,
196
+ urltoBlob,
197
+ urltoImage,
198
+ compress,
199
+ compressAccurately,
200
+ };
@@ -0,0 +1,31 @@
1
+ export enum EImageType {
2
+ "PNG" = "image/png",
3
+ "JPEG" = "image/jpeg",
4
+ "GIF" = "image/gif",
5
+ }
6
+
7
+ interface IBaseConfig {
8
+ [key: string]: any;
9
+ }
10
+
11
+ export interface Image2CanvasConfig extends IBaseConfig {
12
+ width?: number;
13
+ height?: number;
14
+ scale?: number;
15
+ orientation?: number;
16
+ }
17
+
18
+ export interface ICompressConfig extends Image2CanvasConfig {
19
+ quality?: number;
20
+ type?: EImageType;
21
+ }
22
+
23
+ export interface compressAccuratelyConfig extends Image2CanvasConfig {
24
+ size?: number;
25
+ accuracy?: number;
26
+ type?: EImageType;
27
+ }
28
+
29
+ export function checkImageType(type: EImageType) {
30
+ return ["image/png", "image/jpeg", "image/gif"].some((i) => i === type);
31
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 通过一个图片的url加载所需要的File(Blob)对象
3
+ *
4
+ * @param {string} url - 图片URL
5
+ * @returns {Promise(Blob)}
6
+ *
7
+ */
8
+ export default function urltoBlob(url: string): Promise<Blob> {
9
+ return fetch(url).then((response) => response.blob());
10
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 通过一个图片的url加载所需要的image对象
3
+ *
4
+ * @param {string} url - 图片URL
5
+ * @returns {Promise(Image)}
6
+ */
7
+ export default function urltoImage(url: string): Promise<HTMLImageElement> {
8
+ return new Promise((resolve, reject) => {
9
+ const img = new Image();
10
+ img.onload = () => resolve(img);
11
+ img.onerror = () =>
12
+ reject(
13
+ new Error(
14
+ "urltoImage(): Image failed to load, please check the image URL"
15
+ )
16
+ );
17
+ img.src = url;
18
+ });
19
+ }
@@ -0,0 +1,128 @@
1
+ interface UsePrintReturn {
2
+ printHtml: (domNode: string) => void;
3
+ printHtmlElement: (elementArray: Element[]) => void;
4
+ }
5
+ /**
6
+ * ==============================================
7
+ * 打印页面元素
8
+ * ==============================================
9
+ */
10
+ export default function usePrintHtml(): UsePrintReturn {
11
+ /**
12
+ * 打印
13
+ * @param html 打印内容
14
+ */
15
+ function print(htmlStr: string) {
16
+ let style = getStyle();
17
+ let container = getContainer(htmlStr);
18
+
19
+ document.body.appendChild(style);
20
+ document.body.appendChild(container);
21
+
22
+ getLoadPromise(container).then(() => {
23
+ window.print();
24
+ document.body.removeChild(style);
25
+ document.body.removeChild(container);
26
+ });
27
+ }
28
+
29
+ /**
30
+ * 设置默认打印样式
31
+ * @return {*}
32
+ */
33
+ function getStyle(value?: string) {
34
+ let styleContent = `#print-container {
35
+ display: none;
36
+ }
37
+ @media print {
38
+ body > :not(.print-container) {
39
+ display: none;
40
+ }
41
+ html,
42
+ body {
43
+ display: block !important;
44
+ }
45
+ #print-container {
46
+ display: block;
47
+ }
48
+ }`;
49
+ let style = document.createElement("style");
50
+ style.innerHTML = value || styleContent;
51
+ return style;
52
+ }
53
+
54
+ /**
55
+ * 清空打印内容
56
+ */
57
+ function cleanPrint() {
58
+ let div = document.getElementById("print-container");
59
+ if (!!div) {
60
+ document?.querySelector("body")?.removeChild(div);
61
+ }
62
+ }
63
+
64
+ /**
65
+ * 新建DOM,将需要打印的内容填充到DOM
66
+ * @param html html内容
67
+ * @return {*}
68
+ */
69
+ function getContainer(html: string) {
70
+ cleanPrint();
71
+ let container = document.createElement("div");
72
+ container.setAttribute("id", "print-container");
73
+ container.innerHTML = html;
74
+ return container;
75
+ }
76
+
77
+ /**
78
+ * 图片完全加载后再调用打印方法
79
+ * @param dom 需要打印的DOM
80
+ * @return {*}
81
+ */
82
+ function getLoadPromise(dom: Element): Promise<void> {
83
+ let imgDoms = dom.querySelectorAll("img");
84
+ const imgs: Element[] = [].slice.call(imgDoms);
85
+ if (imgs.length === 0) {
86
+ return Promise.resolve();
87
+ }
88
+ let finishedCount = 0;
89
+ return new Promise((resolve) => {
90
+ function check() {
91
+ finishedCount++;
92
+ if (finishedCount === imgs.length) {
93
+ resolve();
94
+ }
95
+ }
96
+ imgs.forEach((img) => {
97
+ img.addEventListener("load", check);
98
+ img.addEventListener("error", check);
99
+ });
100
+ });
101
+ }
102
+
103
+ /**
104
+ * 打印HTML内容
105
+ * @param domNode DOM节点
106
+ */
107
+ function printHtml(domNode: string): void {
108
+ const printForm = document.querySelector(domNode);
109
+ printForm && print(printForm.innerHTML);
110
+ }
111
+
112
+ /**
113
+ * 打印多个HTML内容
114
+ * @param elementArray DOM元素数组
115
+ */
116
+ function printHtmlElement(elementArray: Element[]): void {
117
+ let htmlConent = "";
118
+ for (let i = 0; i < elementArray.length; i++) {
119
+ htmlConent += elementArray[i].outerHTML;
120
+ }
121
+ htmlConent && print(htmlConent);
122
+ }
123
+
124
+ return {
125
+ printHtml,
126
+ printHtmlElement,
127
+ };
128
+ }