vanilla-jui 1.5.45 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.ts +123 -64
- package/dist/index.js +1 -1
- package/dist/index.umd.js +1 -1
- package/package.json +1 -1
- package/src/components/form.ts +1 -1
- package/src/index.ts +2 -3
- package/src/utilities/compress.ts +167 -0
- /package/src/{validation → utilities}/validator.ts +0 -0
package/package.json
CHANGED
package/src/components/form.ts
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
import {
|
|
30
30
|
createValidator,
|
|
31
31
|
type ValidatorClassNameConfig,
|
|
32
|
-
} from '../
|
|
32
|
+
} from '../utilities/validator.ts';
|
|
33
33
|
import { createLoading } from '../primitives/loading.ts';
|
|
34
34
|
import { translate } from '../utilities/locale.ts';
|
|
35
35
|
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,8 @@ export * from './utilities/timer.ts';
|
|
|
13
13
|
export * from './utilities/types.ts';
|
|
14
14
|
export * from './utilities/state.ts';
|
|
15
15
|
export * from './utilities/refs.ts';
|
|
16
|
+
export * from './utilities/validator.ts';
|
|
17
|
+
export * from './utilities/compress.ts';
|
|
16
18
|
export * from './core/scheduler.ts';
|
|
17
19
|
export * from './core/view.ts';
|
|
18
20
|
export * from './core/motion.ts';
|
|
@@ -29,9 +31,6 @@ export * from './primitives/theme.ts';
|
|
|
29
31
|
export * from './primitives/parabola.ts';
|
|
30
32
|
export * from './primitives/sticky.ts';
|
|
31
33
|
|
|
32
|
-
// Validation
|
|
33
|
-
export * from './validation/validator.ts';
|
|
34
|
-
|
|
35
34
|
// Components
|
|
36
35
|
export * from './core/component.ts';
|
|
37
36
|
export * from './components/toc.ts';
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
export interface CompressOptions {
|
|
2
|
+
/** 压缩质量,范围 0-1,默认 0.7 */
|
|
3
|
+
quality?: number;
|
|
4
|
+
/** 目标宽度(像素),不指定则按原图比例缩放 */
|
|
5
|
+
width?: number;
|
|
6
|
+
/** 目标高度(像素),不指定则按原图比例缩放 */
|
|
7
|
+
height?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ImgCompressInstance {
|
|
11
|
+
/**
|
|
12
|
+
* 将图片路径转换为压缩后的 base64 数据
|
|
13
|
+
* @param path - 图片文件路径或 base64 字符串
|
|
14
|
+
* @param callback - 压缩完成后的回调函数,接收 base64 字符串作为参数
|
|
15
|
+
*/
|
|
16
|
+
canvasDataURL: (path: string, callback: (base64: string) => void) => void;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 压缩文件对象
|
|
20
|
+
* @param file - 文件对象(Blob 或 File)
|
|
21
|
+
* @param callback - 压缩完成后的回调函数,接收 base64 字符串作为参数
|
|
22
|
+
*/
|
|
23
|
+
photoCompress: (file: Blob, callback: (base64: string) => void) => void;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 将 base64 字符串转换为 Blob 对象
|
|
27
|
+
* @param urlData - base64 数据(包含 data:image 前缀)
|
|
28
|
+
* @returns Blob 对象,如果解析失败则返回 undefined
|
|
29
|
+
*/
|
|
30
|
+
convertBase64UrlToBlob: (urlData: string) => Blob | undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** 单例缓存 */
|
|
34
|
+
let singletonInstance: ImgCompressInstance | null = null;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 将 base64 字符串转换为 Blob 对象
|
|
38
|
+
* @param urlData - base64 数据(包含 data:image 前缀)
|
|
39
|
+
* @returns Blob 对象,如果解析失败则返回 undefined
|
|
40
|
+
*/
|
|
41
|
+
function convertBase64UrlToBlob(urlData: string): Blob | undefined {
|
|
42
|
+
const arr = urlData.split(',');
|
|
43
|
+
const mimeMatch = arr[0].match(/:(.*?);/);
|
|
44
|
+
if (!mimeMatch) return;
|
|
45
|
+
|
|
46
|
+
const mime = mimeMatch[1];
|
|
47
|
+
const binaryString = atob(arr[1]);
|
|
48
|
+
const length = binaryString.length;
|
|
49
|
+
const uint8Array = new Uint8Array(length);
|
|
50
|
+
|
|
51
|
+
for (let i = 0; i < length; i++) {
|
|
52
|
+
uint8Array[i] = binaryString.charCodeAt(i);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return new Blob([uint8Array], { type: mime });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 创建压缩实例的核心工厂函数
|
|
60
|
+
*/
|
|
61
|
+
function createCompressInstance(
|
|
62
|
+
options?: CompressOptions
|
|
63
|
+
): ImgCompressInstance {
|
|
64
|
+
const { quality = 0.7, width, height } = options ?? {};
|
|
65
|
+
const config = { quality, width, height };
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
canvasDataURL(path: string, callback: (base64: string) => void): void {
|
|
69
|
+
const img = new Image();
|
|
70
|
+
img.src = path;
|
|
71
|
+
|
|
72
|
+
img.onload = (e: Event): void => {
|
|
73
|
+
const target = e.target as HTMLImageElement;
|
|
74
|
+
const { width: originalWidth, height: originalHeight } = target;
|
|
75
|
+
const scale = originalWidth / originalHeight;
|
|
76
|
+
|
|
77
|
+
const w = config.width ?? originalWidth;
|
|
78
|
+
const h = config.height ?? w / scale;
|
|
79
|
+
|
|
80
|
+
const canvas = document.createElement('canvas');
|
|
81
|
+
const ctx = canvas.getContext('2d');
|
|
82
|
+
|
|
83
|
+
canvas.width = w;
|
|
84
|
+
canvas.height = h;
|
|
85
|
+
|
|
86
|
+
ctx?.drawImage(target, 0, 0, w, h);
|
|
87
|
+
|
|
88
|
+
const base64 = canvas.toDataURL('image/jpeg', config.quality);
|
|
89
|
+
callback(base64);
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
photoCompress(file: Blob, callback: (base64: string) => void): void {
|
|
94
|
+
const reader = new FileReader();
|
|
95
|
+
|
|
96
|
+
reader.readAsDataURL(file);
|
|
97
|
+
|
|
98
|
+
reader.onload = (event: ProgressEvent<FileReader>): void => {
|
|
99
|
+
const result = event.target?.result as string;
|
|
100
|
+
this.canvasDataURL(result, callback);
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
convertBase64UrlToBlob,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ==================== public api ====================
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 创建图片压缩实例
|
|
112
|
+
* @param options - 压缩配置选项
|
|
113
|
+
* @param singleton - 是否返回单例,默认 true
|
|
114
|
+
* @returns 图片压缩实例
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* // 获取单例实例(默认)
|
|
118
|
+
* const imgzip = createImgCompress({ quality: 0.8, width: 800 });
|
|
119
|
+
*
|
|
120
|
+
* // 创建新实例
|
|
121
|
+
* const imgzip2 = createImgCompress({ quality: 0.9 }, false);
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
function createImgCompress(
|
|
125
|
+
options?: CompressOptions,
|
|
126
|
+
singleton: boolean = true
|
|
127
|
+
): ImgCompressInstance {
|
|
128
|
+
if (singleton && singletonInstance) {
|
|
129
|
+
return singletonInstance;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const instance = createCompressInstance(options);
|
|
133
|
+
|
|
134
|
+
if (singleton) {
|
|
135
|
+
singletonInstance = instance;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return instance;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* 获取单例实例(如果不存在则创建)
|
|
143
|
+
* @param options - 压缩配置选项(仅在首次创建时生效)
|
|
144
|
+
* @returns 单例实例
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* const imgzip = getImgCompressInstance({ quality: 0.8 });
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
function getImgCompressInstance(
|
|
151
|
+
options?: CompressOptions
|
|
152
|
+
): ImgCompressInstance {
|
|
153
|
+
if (!singletonInstance) {
|
|
154
|
+
singletonInstance = createCompressInstance(options);
|
|
155
|
+
}
|
|
156
|
+
return singletonInstance;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 重置单例实例(用于测试或重新配置)
|
|
161
|
+
*/
|
|
162
|
+
function resetImgCompressInstance(): void {
|
|
163
|
+
singletonInstance = null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export { createImgCompress, getImgCompressInstance, resetImgCompressInstance };
|
|
167
|
+
export default createImgCompress;
|
|
File without changes
|