sculp-js 1.10.1 → 1.10.3
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 +1 -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 +1 -1
- package/lib/cjs/download.js +1 -1
- package/lib/cjs/easing.js +1 -1
- package/lib/cjs/file.js +63 -31
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/lib/cjs/we-decode.js +1 -1
- package/lib/es/array.js +1 -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 +1 -1
- package/lib/es/download.js +1 -1
- package/lib/es/easing.js +1 -1
- package/lib/es/file.js +64 -32
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/lib/es/we-decode.js +1 -1
- package/lib/index.d.ts +7 -2
- package/lib/umd/index.js +160 -127
- package/package.json +1 -1
package/lib/cjs/array.js
CHANGED
package/lib/cjs/async.js
CHANGED
package/lib/cjs/base64.js
CHANGED
package/lib/cjs/clipboard.js
CHANGED
package/lib/cjs/cloneDeep.js
CHANGED
package/lib/cjs/cookie.js
CHANGED
package/lib/cjs/date.js
CHANGED
package/lib/cjs/dom.js
CHANGED
package/lib/cjs/download.js
CHANGED
package/lib/cjs/easing.js
CHANGED
package/lib/cjs/file.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.10.
|
|
2
|
+
* sculp-js v1.10.3
|
|
3
3
|
* (c) 2023-present chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
9
|
var type = require('./type.js');
|
|
10
|
-
var weDecode = require('./we-decode.js');
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* 判断是否支持canvas
|
|
@@ -65,15 +64,35 @@ function calculateSize({ maxWidth, maxHeight, originWidth, originHeight }) {
|
|
|
65
64
|
/**
|
|
66
65
|
* 根据原始图片的不同尺寸计算等比例缩放后的宽高尺寸
|
|
67
66
|
*
|
|
68
|
-
* @param {number} sizeKB
|
|
69
|
-
* @param {number}
|
|
70
|
-
* @param {number}
|
|
71
|
-
* @
|
|
67
|
+
* @param {number} sizeKB Image volume size, unit KB
|
|
68
|
+
* @param {number} maxSize Image max size
|
|
69
|
+
* @param {number} originWidth Image original width, unit px
|
|
70
|
+
* @param {number} originHeight Image original height, unit px
|
|
71
|
+
* @returns {*} {width, height}
|
|
72
72
|
*/
|
|
73
|
-
function scalingByAspectRatio({ sizeKB, originWidth, originHeight }) {
|
|
73
|
+
function scalingByAspectRatio({ sizeKB, maxSize, originWidth, originHeight }) {
|
|
74
74
|
let targetWidth = originWidth, targetHeight = originHeight;
|
|
75
|
-
if (
|
|
76
|
-
|
|
75
|
+
if (type.isNumber(maxSize)) {
|
|
76
|
+
const { width, height } = calculateSize({ maxWidth: maxSize, maxHeight: maxSize, originWidth, originHeight });
|
|
77
|
+
targetWidth = width;
|
|
78
|
+
targetHeight = height;
|
|
79
|
+
}
|
|
80
|
+
else if (sizeKB < 500) {
|
|
81
|
+
// [50KB, 500KB)
|
|
82
|
+
const maxWidth = 1200, maxHeight = 1200;
|
|
83
|
+
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
84
|
+
targetWidth = width;
|
|
85
|
+
targetHeight = height;
|
|
86
|
+
}
|
|
87
|
+
else if (sizeKB < 5 * 1024) {
|
|
88
|
+
// [500KB, 5MB)
|
|
89
|
+
const maxWidth = 1400, maxHeight = 1400;
|
|
90
|
+
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
91
|
+
targetWidth = width;
|
|
92
|
+
targetHeight = height;
|
|
93
|
+
}
|
|
94
|
+
else if (sizeKB < 10 * 1024) {
|
|
95
|
+
// [5MB, 10MB)
|
|
77
96
|
const maxWidth = 1600, maxHeight = 1600;
|
|
78
97
|
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
79
98
|
targetWidth = width;
|
|
@@ -81,7 +100,7 @@ function scalingByAspectRatio({ sizeKB, originWidth, originHeight }) {
|
|
|
81
100
|
}
|
|
82
101
|
else if (10 * 1024 <= sizeKB) {
|
|
83
102
|
// [10MB, Infinity)
|
|
84
|
-
const maxWidth = originWidth > 15000 ? 8192 : originWidth > 10000 ? 4096 :
|
|
103
|
+
const maxWidth = originWidth > 15000 ? 8192 : originWidth > 10000 ? 4096 : 2048, maxHeight = originHeight > 15000 ? 8192 : originHeight > 10000 ? 4096 : 2048;
|
|
85
104
|
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
86
105
|
targetWidth = width;
|
|
87
106
|
targetHeight = height;
|
|
@@ -89,46 +108,59 @@ function scalingByAspectRatio({ sizeKB, originWidth, originHeight }) {
|
|
|
89
108
|
return { width: targetWidth, height: targetHeight };
|
|
90
109
|
}
|
|
91
110
|
/**
|
|
92
|
-
* Web端:等比例压缩图片批量处理 (size小于
|
|
111
|
+
* Web端:等比例压缩图片批量处理 (size小于50KB,不压缩), 支持压缩全景图或长截图
|
|
112
|
+
*
|
|
113
|
+
* 1. 默认根据图片原始size及宽高适当地调整quality、width、height
|
|
114
|
+
* 2. 可指定压缩的图片质量 quality(若不指定则根据原始图片大小来计算), 来适当调整width、height
|
|
115
|
+
* 3. 可指定压缩的图片最大宽高 maxSize(若不指定则根据原始图片宽高来计算), 满足大屏幕图片展示的场景
|
|
93
116
|
*
|
|
94
117
|
* @param {File | FileList} file 图片或图片数组
|
|
95
|
-
* @param {ICompressOptions} options 压缩图片配置项,default: {
|
|
118
|
+
* @param {ICompressOptions} options 压缩图片配置项,default: {mime:'image/jpeg'}
|
|
96
119
|
* @returns {Promise<object> | undefined}
|
|
97
120
|
*/
|
|
98
|
-
function compressImg(file, options = {
|
|
121
|
+
function compressImg(file, options = { mime: 'image/jpeg' }) {
|
|
99
122
|
if (!(file instanceof File || file instanceof FileList)) {
|
|
100
123
|
throw new Error(`${file} require be File or FileList`);
|
|
101
124
|
}
|
|
102
125
|
else if (!supportCanvas()) {
|
|
103
126
|
throw new Error(`Current runtime environment not support Canvas`);
|
|
104
127
|
}
|
|
105
|
-
const { quality
|
|
106
|
-
let targetQuality = quality;
|
|
107
|
-
if (
|
|
128
|
+
const { quality, mime = 'image/jpeg', maxSize: size } = type.isObject(options) ? options : {};
|
|
129
|
+
let targetQuality = quality, maxSize;
|
|
130
|
+
if (quality) {
|
|
131
|
+
targetQuality = quality;
|
|
132
|
+
}
|
|
133
|
+
else if (file instanceof File) {
|
|
108
134
|
const sizeKB = +parseInt((file.size / 1024).toFixed(2));
|
|
109
|
-
if (sizeKB < 1 *
|
|
135
|
+
if (sizeKB < 1 * 50) {
|
|
136
|
+
targetQuality = 1;
|
|
137
|
+
}
|
|
138
|
+
else if (sizeKB < 1 * 1024) {
|
|
110
139
|
targetQuality = 0.85;
|
|
111
140
|
}
|
|
112
|
-
else if (sizeKB
|
|
113
|
-
targetQuality = 0.
|
|
141
|
+
else if (sizeKB < 5 * 1024) {
|
|
142
|
+
targetQuality = 0.8;
|
|
114
143
|
}
|
|
115
|
-
else
|
|
144
|
+
else {
|
|
116
145
|
targetQuality = 0.75;
|
|
117
146
|
}
|
|
118
|
-
else if (sizeKB >= 10 * 1024) {
|
|
119
|
-
targetQuality = 0.92;
|
|
120
|
-
}
|
|
121
147
|
}
|
|
122
|
-
if (
|
|
123
|
-
|
|
148
|
+
if (type.isNumber(size)) {
|
|
149
|
+
maxSize = size >= 1200 ? size : 1200;
|
|
124
150
|
}
|
|
125
151
|
if (file instanceof FileList) {
|
|
126
|
-
return Promise.all(Array.from(file).map(el => compressImg(el, { mime:
|
|
152
|
+
return Promise.all(Array.from(file).map(el => compressImg(el, { maxSize, mime: mime, quality: targetQuality }))); // 如果是 file 数组返回 Promise 数组
|
|
127
153
|
}
|
|
128
154
|
else if (file instanceof File) {
|
|
129
155
|
return new Promise(resolve => {
|
|
156
|
+
const ext = {
|
|
157
|
+
'image/webp': 'webp',
|
|
158
|
+
'image/jpeg': 'jpg',
|
|
159
|
+
'image/png': 'png'
|
|
160
|
+
};
|
|
161
|
+
const fileName = [...file.name.split('.').slice(0, -1), ext[mime]].join('.');
|
|
130
162
|
const sizeKB = +parseInt((file.size / 1024).toFixed(2));
|
|
131
|
-
if (
|
|
163
|
+
if (sizeKB < 50) {
|
|
132
164
|
resolve({
|
|
133
165
|
file: file
|
|
134
166
|
});
|
|
@@ -143,20 +175,20 @@ function compressImg(file, options = { quality: 0.52, mime: 'image/jpeg' }) {
|
|
|
143
175
|
const context = canvas.getContext('2d');
|
|
144
176
|
const originWidth = image.width;
|
|
145
177
|
const originHeight = image.height;
|
|
146
|
-
const { width, height } = scalingByAspectRatio({ sizeKB, originWidth, originHeight });
|
|
178
|
+
const { width, height } = scalingByAspectRatio({ sizeKB, maxSize, originWidth, originHeight });
|
|
147
179
|
canvas.width = width;
|
|
148
180
|
canvas.height = height;
|
|
149
181
|
context.clearRect(0, 0, width, height);
|
|
150
182
|
context.drawImage(image, 0, 0, width, height); // 绘制 canvas
|
|
151
183
|
const canvasURL = canvas.toDataURL(mime, targetQuality);
|
|
152
|
-
const buffer =
|
|
184
|
+
const buffer = atob(canvasURL.split(',')[1]);
|
|
153
185
|
let length = buffer.length;
|
|
154
186
|
const bufferArray = new Uint8Array(new ArrayBuffer(length));
|
|
155
187
|
while (length--) {
|
|
156
188
|
bufferArray[length] = buffer.charCodeAt(length);
|
|
157
189
|
}
|
|
158
|
-
const miniFile = new File([bufferArray],
|
|
159
|
-
type:
|
|
190
|
+
const miniFile = new File([bufferArray], fileName, {
|
|
191
|
+
type: mime
|
|
160
192
|
});
|
|
161
193
|
resolve({
|
|
162
194
|
file: miniFile,
|
package/lib/cjs/func.js
CHANGED
package/lib/cjs/index.js
CHANGED
package/lib/cjs/isEqual.js
CHANGED
package/lib/cjs/math.js
CHANGED
package/lib/cjs/number.js
CHANGED
package/lib/cjs/object.js
CHANGED
package/lib/cjs/path.js
CHANGED
package/lib/cjs/qs.js
CHANGED
package/lib/cjs/random.js
CHANGED
package/lib/cjs/string.js
CHANGED
package/lib/cjs/tooltip.js
CHANGED
package/lib/cjs/tree.js
CHANGED
package/lib/cjs/type.js
CHANGED
package/lib/cjs/unique.js
CHANGED
package/lib/cjs/url.js
CHANGED
package/lib/cjs/validator.js
CHANGED
package/lib/cjs/variable.js
CHANGED
package/lib/cjs/watermark.js
CHANGED
package/lib/cjs/we-decode.js
CHANGED
package/lib/es/array.js
CHANGED
package/lib/es/async.js
CHANGED
package/lib/es/base64.js
CHANGED
package/lib/es/clipboard.js
CHANGED
package/lib/es/cloneDeep.js
CHANGED
package/lib/es/cookie.js
CHANGED
package/lib/es/date.js
CHANGED
package/lib/es/dom.js
CHANGED
package/lib/es/download.js
CHANGED
package/lib/es/easing.js
CHANGED
package/lib/es/file.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.10.
|
|
2
|
+
* sculp-js v1.10.3
|
|
3
3
|
* (c) 2023-present chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { isObject } from './type.js';
|
|
8
|
-
import { weAtob } from './we-decode.js';
|
|
7
|
+
import { isObject, isNumber } from './type.js';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* 判断是否支持canvas
|
|
@@ -63,15 +62,35 @@ function calculateSize({ maxWidth, maxHeight, originWidth, originHeight }) {
|
|
|
63
62
|
/**
|
|
64
63
|
* 根据原始图片的不同尺寸计算等比例缩放后的宽高尺寸
|
|
65
64
|
*
|
|
66
|
-
* @param {number} sizeKB
|
|
67
|
-
* @param {number}
|
|
68
|
-
* @param {number}
|
|
69
|
-
* @
|
|
65
|
+
* @param {number} sizeKB Image volume size, unit KB
|
|
66
|
+
* @param {number} maxSize Image max size
|
|
67
|
+
* @param {number} originWidth Image original width, unit px
|
|
68
|
+
* @param {number} originHeight Image original height, unit px
|
|
69
|
+
* @returns {*} {width, height}
|
|
70
70
|
*/
|
|
71
|
-
function scalingByAspectRatio({ sizeKB, originWidth, originHeight }) {
|
|
71
|
+
function scalingByAspectRatio({ sizeKB, maxSize, originWidth, originHeight }) {
|
|
72
72
|
let targetWidth = originWidth, targetHeight = originHeight;
|
|
73
|
-
if (
|
|
74
|
-
|
|
73
|
+
if (isNumber(maxSize)) {
|
|
74
|
+
const { width, height } = calculateSize({ maxWidth: maxSize, maxHeight: maxSize, originWidth, originHeight });
|
|
75
|
+
targetWidth = width;
|
|
76
|
+
targetHeight = height;
|
|
77
|
+
}
|
|
78
|
+
else if (sizeKB < 500) {
|
|
79
|
+
// [50KB, 500KB)
|
|
80
|
+
const maxWidth = 1200, maxHeight = 1200;
|
|
81
|
+
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
82
|
+
targetWidth = width;
|
|
83
|
+
targetHeight = height;
|
|
84
|
+
}
|
|
85
|
+
else if (sizeKB < 5 * 1024) {
|
|
86
|
+
// [500KB, 5MB)
|
|
87
|
+
const maxWidth = 1400, maxHeight = 1400;
|
|
88
|
+
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
89
|
+
targetWidth = width;
|
|
90
|
+
targetHeight = height;
|
|
91
|
+
}
|
|
92
|
+
else if (sizeKB < 10 * 1024) {
|
|
93
|
+
// [5MB, 10MB)
|
|
75
94
|
const maxWidth = 1600, maxHeight = 1600;
|
|
76
95
|
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
77
96
|
targetWidth = width;
|
|
@@ -79,7 +98,7 @@ function scalingByAspectRatio({ sizeKB, originWidth, originHeight }) {
|
|
|
79
98
|
}
|
|
80
99
|
else if (10 * 1024 <= sizeKB) {
|
|
81
100
|
// [10MB, Infinity)
|
|
82
|
-
const maxWidth = originWidth > 15000 ? 8192 : originWidth > 10000 ? 4096 :
|
|
101
|
+
const maxWidth = originWidth > 15000 ? 8192 : originWidth > 10000 ? 4096 : 2048, maxHeight = originHeight > 15000 ? 8192 : originHeight > 10000 ? 4096 : 2048;
|
|
83
102
|
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
84
103
|
targetWidth = width;
|
|
85
104
|
targetHeight = height;
|
|
@@ -87,46 +106,59 @@ function scalingByAspectRatio({ sizeKB, originWidth, originHeight }) {
|
|
|
87
106
|
return { width: targetWidth, height: targetHeight };
|
|
88
107
|
}
|
|
89
108
|
/**
|
|
90
|
-
* Web端:等比例压缩图片批量处理 (size小于
|
|
109
|
+
* Web端:等比例压缩图片批量处理 (size小于50KB,不压缩), 支持压缩全景图或长截图
|
|
110
|
+
*
|
|
111
|
+
* 1. 默认根据图片原始size及宽高适当地调整quality、width、height
|
|
112
|
+
* 2. 可指定压缩的图片质量 quality(若不指定则根据原始图片大小来计算), 来适当调整width、height
|
|
113
|
+
* 3. 可指定压缩的图片最大宽高 maxSize(若不指定则根据原始图片宽高来计算), 满足大屏幕图片展示的场景
|
|
91
114
|
*
|
|
92
115
|
* @param {File | FileList} file 图片或图片数组
|
|
93
|
-
* @param {ICompressOptions} options 压缩图片配置项,default: {
|
|
116
|
+
* @param {ICompressOptions} options 压缩图片配置项,default: {mime:'image/jpeg'}
|
|
94
117
|
* @returns {Promise<object> | undefined}
|
|
95
118
|
*/
|
|
96
|
-
function compressImg(file, options = {
|
|
119
|
+
function compressImg(file, options = { mime: 'image/jpeg' }) {
|
|
97
120
|
if (!(file instanceof File || file instanceof FileList)) {
|
|
98
121
|
throw new Error(`${file} require be File or FileList`);
|
|
99
122
|
}
|
|
100
123
|
else if (!supportCanvas()) {
|
|
101
124
|
throw new Error(`Current runtime environment not support Canvas`);
|
|
102
125
|
}
|
|
103
|
-
const { quality
|
|
104
|
-
let targetQuality = quality;
|
|
105
|
-
if (
|
|
126
|
+
const { quality, mime = 'image/jpeg', maxSize: size } = isObject(options) ? options : {};
|
|
127
|
+
let targetQuality = quality, maxSize;
|
|
128
|
+
if (quality) {
|
|
129
|
+
targetQuality = quality;
|
|
130
|
+
}
|
|
131
|
+
else if (file instanceof File) {
|
|
106
132
|
const sizeKB = +parseInt((file.size / 1024).toFixed(2));
|
|
107
|
-
if (sizeKB < 1 *
|
|
133
|
+
if (sizeKB < 1 * 50) {
|
|
134
|
+
targetQuality = 1;
|
|
135
|
+
}
|
|
136
|
+
else if (sizeKB < 1 * 1024) {
|
|
108
137
|
targetQuality = 0.85;
|
|
109
138
|
}
|
|
110
|
-
else if (sizeKB
|
|
111
|
-
targetQuality = 0.
|
|
139
|
+
else if (sizeKB < 5 * 1024) {
|
|
140
|
+
targetQuality = 0.8;
|
|
112
141
|
}
|
|
113
|
-
else
|
|
142
|
+
else {
|
|
114
143
|
targetQuality = 0.75;
|
|
115
144
|
}
|
|
116
|
-
else if (sizeKB >= 10 * 1024) {
|
|
117
|
-
targetQuality = 0.92;
|
|
118
|
-
}
|
|
119
145
|
}
|
|
120
|
-
if (
|
|
121
|
-
|
|
146
|
+
if (isNumber(size)) {
|
|
147
|
+
maxSize = size >= 1200 ? size : 1200;
|
|
122
148
|
}
|
|
123
149
|
if (file instanceof FileList) {
|
|
124
|
-
return Promise.all(Array.from(file).map(el => compressImg(el, { mime:
|
|
150
|
+
return Promise.all(Array.from(file).map(el => compressImg(el, { maxSize, mime: mime, quality: targetQuality }))); // 如果是 file 数组返回 Promise 数组
|
|
125
151
|
}
|
|
126
152
|
else if (file instanceof File) {
|
|
127
153
|
return new Promise(resolve => {
|
|
154
|
+
const ext = {
|
|
155
|
+
'image/webp': 'webp',
|
|
156
|
+
'image/jpeg': 'jpg',
|
|
157
|
+
'image/png': 'png'
|
|
158
|
+
};
|
|
159
|
+
const fileName = [...file.name.split('.').slice(0, -1), ext[mime]].join('.');
|
|
128
160
|
const sizeKB = +parseInt((file.size / 1024).toFixed(2));
|
|
129
|
-
if (
|
|
161
|
+
if (sizeKB < 50) {
|
|
130
162
|
resolve({
|
|
131
163
|
file: file
|
|
132
164
|
});
|
|
@@ -141,20 +173,20 @@ function compressImg(file, options = { quality: 0.52, mime: 'image/jpeg' }) {
|
|
|
141
173
|
const context = canvas.getContext('2d');
|
|
142
174
|
const originWidth = image.width;
|
|
143
175
|
const originHeight = image.height;
|
|
144
|
-
const { width, height } = scalingByAspectRatio({ sizeKB, originWidth, originHeight });
|
|
176
|
+
const { width, height } = scalingByAspectRatio({ sizeKB, maxSize, originWidth, originHeight });
|
|
145
177
|
canvas.width = width;
|
|
146
178
|
canvas.height = height;
|
|
147
179
|
context.clearRect(0, 0, width, height);
|
|
148
180
|
context.drawImage(image, 0, 0, width, height); // 绘制 canvas
|
|
149
181
|
const canvasURL = canvas.toDataURL(mime, targetQuality);
|
|
150
|
-
const buffer =
|
|
182
|
+
const buffer = atob(canvasURL.split(',')[1]);
|
|
151
183
|
let length = buffer.length;
|
|
152
184
|
const bufferArray = new Uint8Array(new ArrayBuffer(length));
|
|
153
185
|
while (length--) {
|
|
154
186
|
bufferArray[length] = buffer.charCodeAt(length);
|
|
155
187
|
}
|
|
156
|
-
const miniFile = new File([bufferArray],
|
|
157
|
-
type:
|
|
188
|
+
const miniFile = new File([bufferArray], fileName, {
|
|
189
|
+
type: mime
|
|
158
190
|
});
|
|
159
191
|
resolve({
|
|
160
192
|
file: miniFile,
|
package/lib/es/func.js
CHANGED
package/lib/es/index.js
CHANGED
package/lib/es/isEqual.js
CHANGED
package/lib/es/math.js
CHANGED
package/lib/es/number.js
CHANGED
package/lib/es/object.js
CHANGED
package/lib/es/path.js
CHANGED
package/lib/es/qs.js
CHANGED
package/lib/es/random.js
CHANGED
package/lib/es/string.js
CHANGED
package/lib/es/tooltip.js
CHANGED
package/lib/es/tree.js
CHANGED
package/lib/es/type.js
CHANGED
package/lib/es/unique.js
CHANGED
package/lib/es/url.js
CHANGED
package/lib/es/validator.js
CHANGED
package/lib/es/variable.js
CHANGED
package/lib/es/watermark.js
CHANGED
package/lib/es/we-decode.js
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -603,12 +603,17 @@ interface ICompressOptions {
|
|
|
603
603
|
quality?: number;
|
|
604
604
|
/** 图片类型 */
|
|
605
605
|
mime?: ImageType;
|
|
606
|
+
maxSize?: number;
|
|
606
607
|
}
|
|
607
608
|
/**
|
|
608
|
-
* Web端:等比例压缩图片批量处理 (size小于
|
|
609
|
+
* Web端:等比例压缩图片批量处理 (size小于50KB,不压缩), 支持压缩全景图或长截图
|
|
610
|
+
*
|
|
611
|
+
* 1. 默认根据图片原始size及宽高适当地调整quality、width、height
|
|
612
|
+
* 2. 可指定压缩的图片质量 quality(若不指定则根据原始图片大小来计算), 来适当调整width、height
|
|
613
|
+
* 3. 可指定压缩的图片最大宽高 maxSize(若不指定则根据原始图片宽高来计算), 满足大屏幕图片展示的场景
|
|
609
614
|
*
|
|
610
615
|
* @param {File | FileList} file 图片或图片数组
|
|
611
|
-
* @param {ICompressOptions} options 压缩图片配置项,default: {
|
|
616
|
+
* @param {ICompressOptions} options 压缩图片配置项,default: {mime:'image/jpeg'}
|
|
612
617
|
* @returns {Promise<object> | undefined}
|
|
613
618
|
*/
|
|
614
619
|
declare function compressImg(file: File | FileList, options?: ICompressOptions): Promise<object> | undefined;
|
package/lib/umd/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.10.
|
|
2
|
+
* sculp-js v1.10.3
|
|
3
3
|
* (c) 2023-present chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -1377,103 +1377,6 @@
|
|
|
1377
1377
|
});
|
|
1378
1378
|
}
|
|
1379
1379
|
|
|
1380
|
-
const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
1381
|
-
// eslint-disable-next-line
|
|
1382
|
-
const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
|
|
1383
|
-
/**
|
|
1384
|
-
* 字符串编码成Base64, 平替浏览器的btoa, 不包含中文的处理 (适用于任何环境,包括小程序)
|
|
1385
|
-
* @param {string} string
|
|
1386
|
-
* @returns {string}
|
|
1387
|
-
*/
|
|
1388
|
-
function weBtoa(string) {
|
|
1389
|
-
// 同window.btoa: 字符串编码成Base64
|
|
1390
|
-
string = String(string);
|
|
1391
|
-
let bitmap, a, b, c, result = '', i = 0;
|
|
1392
|
-
const strLen = string.length;
|
|
1393
|
-
const rest = strLen % 3;
|
|
1394
|
-
for (; i < strLen;) {
|
|
1395
|
-
if ((a = string.charCodeAt(i++)) > 255 || (b = string.charCodeAt(i++)) > 255 || (c = string.charCodeAt(i++)) > 255)
|
|
1396
|
-
throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
|
|
1397
|
-
bitmap = (a << 16) | (b << 8) | c;
|
|
1398
|
-
result +=
|
|
1399
|
-
b64.charAt((bitmap >> 18) & 63) +
|
|
1400
|
-
b64.charAt((bitmap >> 12) & 63) +
|
|
1401
|
-
b64.charAt((bitmap >> 6) & 63) +
|
|
1402
|
-
b64.charAt(bitmap & 63);
|
|
1403
|
-
}
|
|
1404
|
-
return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result;
|
|
1405
|
-
}
|
|
1406
|
-
/**
|
|
1407
|
-
* Base64解码为原始字符串,平替浏览器的atob, 不包含中文的处理(适用于任何环境,包括小程序)
|
|
1408
|
-
* @param {string} string
|
|
1409
|
-
* @returns {string}
|
|
1410
|
-
*/
|
|
1411
|
-
function weAtob(string) {
|
|
1412
|
-
// 同window.atob: Base64解码为原始字符串
|
|
1413
|
-
string = String(string).replace(/[\t\n\f\r ]+/g, '');
|
|
1414
|
-
if (!b64re.test(string))
|
|
1415
|
-
throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
|
|
1416
|
-
string += '=='.slice(2 - (string.length & 3));
|
|
1417
|
-
let bitmap, result = '', r1, r2, i = 0;
|
|
1418
|
-
for (const strLen = string.length; i < strLen;) {
|
|
1419
|
-
bitmap =
|
|
1420
|
-
(b64.indexOf(string.charAt(i++)) << 18) |
|
|
1421
|
-
(b64.indexOf(string.charAt(i++)) << 12) |
|
|
1422
|
-
((r1 = b64.indexOf(string.charAt(i++))) << 6) |
|
|
1423
|
-
(r2 = b64.indexOf(string.charAt(i++)));
|
|
1424
|
-
result +=
|
|
1425
|
-
r1 === 64
|
|
1426
|
-
? String.fromCharCode((bitmap >> 16) & 255)
|
|
1427
|
-
: r2 === 64
|
|
1428
|
-
? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255)
|
|
1429
|
-
: String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255);
|
|
1430
|
-
}
|
|
1431
|
-
return result;
|
|
1432
|
-
}
|
|
1433
|
-
// function b64DecodeUnicode(str) {
|
|
1434
|
-
// return decodeURIComponent(
|
|
1435
|
-
// exports.weAtob(str).replace(/(.)/g, function (p) {
|
|
1436
|
-
// let code = p.charCodeAt(0).toString(16).toUpperCase();
|
|
1437
|
-
// if (code.length < 2) {
|
|
1438
|
-
// code = '0' + code;
|
|
1439
|
-
// }
|
|
1440
|
-
// return '%' + code;
|
|
1441
|
-
// })
|
|
1442
|
-
// );
|
|
1443
|
-
// }
|
|
1444
|
-
// function base64_url_decode(str) {
|
|
1445
|
-
// let output = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
1446
|
-
// switch (output.length % 4) {
|
|
1447
|
-
// case 0:
|
|
1448
|
-
// break;
|
|
1449
|
-
// case 2:
|
|
1450
|
-
// output += '==';
|
|
1451
|
-
// break;
|
|
1452
|
-
// case 3:
|
|
1453
|
-
// output += '=';
|
|
1454
|
-
// break;
|
|
1455
|
-
// default:
|
|
1456
|
-
// throw new Error('Illegal base64url string!');
|
|
1457
|
-
// }
|
|
1458
|
-
// try {
|
|
1459
|
-
// return b64DecodeUnicode(output);
|
|
1460
|
-
// } catch (err) {
|
|
1461
|
-
// return exports.weAtob(output);
|
|
1462
|
-
// }
|
|
1463
|
-
// }
|
|
1464
|
-
// export function weAppJwtDecode(token, options) {
|
|
1465
|
-
// if (typeof token !== 'string') {
|
|
1466
|
-
// throw new Error('Invalid token specified');
|
|
1467
|
-
// }
|
|
1468
|
-
// options = options || {};
|
|
1469
|
-
// const pos = options.header === true ? 0 : 1;
|
|
1470
|
-
// try {
|
|
1471
|
-
// return JSON.parse(base64_url_decode(token.split('.')[pos]));
|
|
1472
|
-
// } catch (e) {
|
|
1473
|
-
// throw new Error('Invalid token specified: ' + (e as Error).message);
|
|
1474
|
-
// }
|
|
1475
|
-
// }
|
|
1476
|
-
|
|
1477
1380
|
/**
|
|
1478
1381
|
* 判断是否支持canvas
|
|
1479
1382
|
* @returns {boolean}
|
|
@@ -1530,15 +1433,35 @@
|
|
|
1530
1433
|
/**
|
|
1531
1434
|
* 根据原始图片的不同尺寸计算等比例缩放后的宽高尺寸
|
|
1532
1435
|
*
|
|
1533
|
-
* @param {number} sizeKB
|
|
1534
|
-
* @param {number}
|
|
1535
|
-
* @param {number}
|
|
1536
|
-
* @
|
|
1436
|
+
* @param {number} sizeKB Image volume size, unit KB
|
|
1437
|
+
* @param {number} maxSize Image max size
|
|
1438
|
+
* @param {number} originWidth Image original width, unit px
|
|
1439
|
+
* @param {number} originHeight Image original height, unit px
|
|
1440
|
+
* @returns {*} {width, height}
|
|
1537
1441
|
*/
|
|
1538
|
-
function scalingByAspectRatio({ sizeKB, originWidth, originHeight }) {
|
|
1442
|
+
function scalingByAspectRatio({ sizeKB, maxSize, originWidth, originHeight }) {
|
|
1539
1443
|
let targetWidth = originWidth, targetHeight = originHeight;
|
|
1540
|
-
if (
|
|
1541
|
-
|
|
1444
|
+
if (isNumber(maxSize)) {
|
|
1445
|
+
const { width, height } = calculateSize({ maxWidth: maxSize, maxHeight: maxSize, originWidth, originHeight });
|
|
1446
|
+
targetWidth = width;
|
|
1447
|
+
targetHeight = height;
|
|
1448
|
+
}
|
|
1449
|
+
else if (sizeKB < 500) {
|
|
1450
|
+
// [50KB, 500KB)
|
|
1451
|
+
const maxWidth = 1200, maxHeight = 1200;
|
|
1452
|
+
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
1453
|
+
targetWidth = width;
|
|
1454
|
+
targetHeight = height;
|
|
1455
|
+
}
|
|
1456
|
+
else if (sizeKB < 5 * 1024) {
|
|
1457
|
+
// [500KB, 5MB)
|
|
1458
|
+
const maxWidth = 1400, maxHeight = 1400;
|
|
1459
|
+
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
1460
|
+
targetWidth = width;
|
|
1461
|
+
targetHeight = height;
|
|
1462
|
+
}
|
|
1463
|
+
else if (sizeKB < 10 * 1024) {
|
|
1464
|
+
// [5MB, 10MB)
|
|
1542
1465
|
const maxWidth = 1600, maxHeight = 1600;
|
|
1543
1466
|
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
1544
1467
|
targetWidth = width;
|
|
@@ -1546,7 +1469,7 @@
|
|
|
1546
1469
|
}
|
|
1547
1470
|
else if (10 * 1024 <= sizeKB) {
|
|
1548
1471
|
// [10MB, Infinity)
|
|
1549
|
-
const maxWidth = originWidth > 15000 ? 8192 : originWidth > 10000 ? 4096 :
|
|
1472
|
+
const maxWidth = originWidth > 15000 ? 8192 : originWidth > 10000 ? 4096 : 2048, maxHeight = originHeight > 15000 ? 8192 : originHeight > 10000 ? 4096 : 2048;
|
|
1550
1473
|
const { width, height } = calculateSize({ maxWidth, maxHeight, originWidth, originHeight });
|
|
1551
1474
|
targetWidth = width;
|
|
1552
1475
|
targetHeight = height;
|
|
@@ -1554,46 +1477,59 @@
|
|
|
1554
1477
|
return { width: targetWidth, height: targetHeight };
|
|
1555
1478
|
}
|
|
1556
1479
|
/**
|
|
1557
|
-
* Web端:等比例压缩图片批量处理 (size小于
|
|
1480
|
+
* Web端:等比例压缩图片批量处理 (size小于50KB,不压缩), 支持压缩全景图或长截图
|
|
1481
|
+
*
|
|
1482
|
+
* 1. 默认根据图片原始size及宽高适当地调整quality、width、height
|
|
1483
|
+
* 2. 可指定压缩的图片质量 quality(若不指定则根据原始图片大小来计算), 来适当调整width、height
|
|
1484
|
+
* 3. 可指定压缩的图片最大宽高 maxSize(若不指定则根据原始图片宽高来计算), 满足大屏幕图片展示的场景
|
|
1558
1485
|
*
|
|
1559
1486
|
* @param {File | FileList} file 图片或图片数组
|
|
1560
|
-
* @param {ICompressOptions} options 压缩图片配置项,default: {
|
|
1487
|
+
* @param {ICompressOptions} options 压缩图片配置项,default: {mime:'image/jpeg'}
|
|
1561
1488
|
* @returns {Promise<object> | undefined}
|
|
1562
1489
|
*/
|
|
1563
|
-
function compressImg(file, options = {
|
|
1490
|
+
function compressImg(file, options = { mime: 'image/jpeg' }) {
|
|
1564
1491
|
if (!(file instanceof File || file instanceof FileList)) {
|
|
1565
1492
|
throw new Error(`${file} require be File or FileList`);
|
|
1566
1493
|
}
|
|
1567
1494
|
else if (!supportCanvas()) {
|
|
1568
1495
|
throw new Error(`Current runtime environment not support Canvas`);
|
|
1569
1496
|
}
|
|
1570
|
-
const { quality
|
|
1571
|
-
let targetQuality = quality;
|
|
1572
|
-
if (
|
|
1497
|
+
const { quality, mime = 'image/jpeg', maxSize: size } = isObject(options) ? options : {};
|
|
1498
|
+
let targetQuality = quality, maxSize;
|
|
1499
|
+
if (quality) {
|
|
1500
|
+
targetQuality = quality;
|
|
1501
|
+
}
|
|
1502
|
+
else if (file instanceof File) {
|
|
1573
1503
|
const sizeKB = +parseInt((file.size / 1024).toFixed(2));
|
|
1574
|
-
if (sizeKB < 1 *
|
|
1504
|
+
if (sizeKB < 1 * 50) {
|
|
1505
|
+
targetQuality = 1;
|
|
1506
|
+
}
|
|
1507
|
+
else if (sizeKB < 1 * 1024) {
|
|
1575
1508
|
targetQuality = 0.85;
|
|
1576
1509
|
}
|
|
1577
|
-
else if (sizeKB
|
|
1578
|
-
targetQuality = 0.
|
|
1510
|
+
else if (sizeKB < 5 * 1024) {
|
|
1511
|
+
targetQuality = 0.8;
|
|
1579
1512
|
}
|
|
1580
|
-
else
|
|
1513
|
+
else {
|
|
1581
1514
|
targetQuality = 0.75;
|
|
1582
1515
|
}
|
|
1583
|
-
else if (sizeKB >= 10 * 1024) {
|
|
1584
|
-
targetQuality = 0.92;
|
|
1585
|
-
}
|
|
1586
1516
|
}
|
|
1587
|
-
if (
|
|
1588
|
-
|
|
1517
|
+
if (isNumber(size)) {
|
|
1518
|
+
maxSize = size >= 1200 ? size : 1200;
|
|
1589
1519
|
}
|
|
1590
1520
|
if (file instanceof FileList) {
|
|
1591
|
-
return Promise.all(Array.from(file).map(el => compressImg(el, { mime:
|
|
1521
|
+
return Promise.all(Array.from(file).map(el => compressImg(el, { maxSize, mime: mime, quality: targetQuality }))); // 如果是 file 数组返回 Promise 数组
|
|
1592
1522
|
}
|
|
1593
1523
|
else if (file instanceof File) {
|
|
1594
1524
|
return new Promise(resolve => {
|
|
1525
|
+
const ext = {
|
|
1526
|
+
'image/webp': 'webp',
|
|
1527
|
+
'image/jpeg': 'jpg',
|
|
1528
|
+
'image/png': 'png'
|
|
1529
|
+
};
|
|
1530
|
+
const fileName = [...file.name.split('.').slice(0, -1), ext[mime]].join('.');
|
|
1595
1531
|
const sizeKB = +parseInt((file.size / 1024).toFixed(2));
|
|
1596
|
-
if (
|
|
1532
|
+
if (sizeKB < 50) {
|
|
1597
1533
|
resolve({
|
|
1598
1534
|
file: file
|
|
1599
1535
|
});
|
|
@@ -1608,20 +1544,20 @@
|
|
|
1608
1544
|
const context = canvas.getContext('2d');
|
|
1609
1545
|
const originWidth = image.width;
|
|
1610
1546
|
const originHeight = image.height;
|
|
1611
|
-
const { width, height } = scalingByAspectRatio({ sizeKB, originWidth, originHeight });
|
|
1547
|
+
const { width, height } = scalingByAspectRatio({ sizeKB, maxSize, originWidth, originHeight });
|
|
1612
1548
|
canvas.width = width;
|
|
1613
1549
|
canvas.height = height;
|
|
1614
1550
|
context.clearRect(0, 0, width, height);
|
|
1615
1551
|
context.drawImage(image, 0, 0, width, height); // 绘制 canvas
|
|
1616
1552
|
const canvasURL = canvas.toDataURL(mime, targetQuality);
|
|
1617
|
-
const buffer =
|
|
1553
|
+
const buffer = atob(canvasURL.split(',')[1]);
|
|
1618
1554
|
let length = buffer.length;
|
|
1619
1555
|
const bufferArray = new Uint8Array(new ArrayBuffer(length));
|
|
1620
1556
|
while (length--) {
|
|
1621
1557
|
bufferArray[length] = buffer.charCodeAt(length);
|
|
1622
1558
|
}
|
|
1623
|
-
const miniFile = new File([bufferArray],
|
|
1624
|
-
type:
|
|
1559
|
+
const miniFile = new File([bufferArray], fileName, {
|
|
1560
|
+
type: mime
|
|
1625
1561
|
});
|
|
1626
1562
|
resolve({
|
|
1627
1563
|
file: miniFile,
|
|
@@ -2539,6 +2475,103 @@
|
|
|
2539
2475
|
return +parseFloat(Number(num).toPrecision(precision));
|
|
2540
2476
|
}
|
|
2541
2477
|
|
|
2478
|
+
const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
2479
|
+
// eslint-disable-next-line
|
|
2480
|
+
const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
|
|
2481
|
+
/**
|
|
2482
|
+
* 字符串编码成Base64, 平替浏览器的btoa, 不包含中文的处理 (适用于任何环境,包括小程序)
|
|
2483
|
+
* @param {string} string
|
|
2484
|
+
* @returns {string}
|
|
2485
|
+
*/
|
|
2486
|
+
function weBtoa(string) {
|
|
2487
|
+
// 同window.btoa: 字符串编码成Base64
|
|
2488
|
+
string = String(string);
|
|
2489
|
+
let bitmap, a, b, c, result = '', i = 0;
|
|
2490
|
+
const strLen = string.length;
|
|
2491
|
+
const rest = strLen % 3;
|
|
2492
|
+
for (; i < strLen;) {
|
|
2493
|
+
if ((a = string.charCodeAt(i++)) > 255 || (b = string.charCodeAt(i++)) > 255 || (c = string.charCodeAt(i++)) > 255)
|
|
2494
|
+
throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
|
|
2495
|
+
bitmap = (a << 16) | (b << 8) | c;
|
|
2496
|
+
result +=
|
|
2497
|
+
b64.charAt((bitmap >> 18) & 63) +
|
|
2498
|
+
b64.charAt((bitmap >> 12) & 63) +
|
|
2499
|
+
b64.charAt((bitmap >> 6) & 63) +
|
|
2500
|
+
b64.charAt(bitmap & 63);
|
|
2501
|
+
}
|
|
2502
|
+
return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result;
|
|
2503
|
+
}
|
|
2504
|
+
/**
|
|
2505
|
+
* Base64解码为原始字符串,平替浏览器的atob, 不包含中文的处理(适用于任何环境,包括小程序)
|
|
2506
|
+
* @param {string} string
|
|
2507
|
+
* @returns {string}
|
|
2508
|
+
*/
|
|
2509
|
+
function weAtob(string) {
|
|
2510
|
+
// 同window.atob: Base64解码为原始字符串
|
|
2511
|
+
string = String(string).replace(/[\t\n\f\r ]+/g, '');
|
|
2512
|
+
if (!b64re.test(string))
|
|
2513
|
+
throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
|
|
2514
|
+
string += '=='.slice(2 - (string.length & 3));
|
|
2515
|
+
let bitmap, result = '', r1, r2, i = 0;
|
|
2516
|
+
for (const strLen = string.length; i < strLen;) {
|
|
2517
|
+
bitmap =
|
|
2518
|
+
(b64.indexOf(string.charAt(i++)) << 18) |
|
|
2519
|
+
(b64.indexOf(string.charAt(i++)) << 12) |
|
|
2520
|
+
((r1 = b64.indexOf(string.charAt(i++))) << 6) |
|
|
2521
|
+
(r2 = b64.indexOf(string.charAt(i++)));
|
|
2522
|
+
result +=
|
|
2523
|
+
r1 === 64
|
|
2524
|
+
? String.fromCharCode((bitmap >> 16) & 255)
|
|
2525
|
+
: r2 === 64
|
|
2526
|
+
? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255)
|
|
2527
|
+
: String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255);
|
|
2528
|
+
}
|
|
2529
|
+
return result;
|
|
2530
|
+
}
|
|
2531
|
+
// function b64DecodeUnicode(str) {
|
|
2532
|
+
// return decodeURIComponent(
|
|
2533
|
+
// exports.weAtob(str).replace(/(.)/g, function (p) {
|
|
2534
|
+
// let code = p.charCodeAt(0).toString(16).toUpperCase();
|
|
2535
|
+
// if (code.length < 2) {
|
|
2536
|
+
// code = '0' + code;
|
|
2537
|
+
// }
|
|
2538
|
+
// return '%' + code;
|
|
2539
|
+
// })
|
|
2540
|
+
// );
|
|
2541
|
+
// }
|
|
2542
|
+
// function base64_url_decode(str) {
|
|
2543
|
+
// let output = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
2544
|
+
// switch (output.length % 4) {
|
|
2545
|
+
// case 0:
|
|
2546
|
+
// break;
|
|
2547
|
+
// case 2:
|
|
2548
|
+
// output += '==';
|
|
2549
|
+
// break;
|
|
2550
|
+
// case 3:
|
|
2551
|
+
// output += '=';
|
|
2552
|
+
// break;
|
|
2553
|
+
// default:
|
|
2554
|
+
// throw new Error('Illegal base64url string!');
|
|
2555
|
+
// }
|
|
2556
|
+
// try {
|
|
2557
|
+
// return b64DecodeUnicode(output);
|
|
2558
|
+
// } catch (err) {
|
|
2559
|
+
// return exports.weAtob(output);
|
|
2560
|
+
// }
|
|
2561
|
+
// }
|
|
2562
|
+
// export function weAppJwtDecode(token, options) {
|
|
2563
|
+
// if (typeof token !== 'string') {
|
|
2564
|
+
// throw new Error('Invalid token specified');
|
|
2565
|
+
// }
|
|
2566
|
+
// options = options || {};
|
|
2567
|
+
// const pos = options.header === true ? 0 : 1;
|
|
2568
|
+
// try {
|
|
2569
|
+
// return JSON.parse(base64_url_decode(token.split('.')[pos]));
|
|
2570
|
+
// } catch (e) {
|
|
2571
|
+
// throw new Error('Invalid token specified: ' + (e as Error).message);
|
|
2572
|
+
// }
|
|
2573
|
+
// }
|
|
2574
|
+
|
|
2542
2575
|
function stringToUint8Array(str) {
|
|
2543
2576
|
const utf8 = encodeURIComponent(str); // 将字符串转换为 UTF-8 编码
|
|
2544
2577
|
const uint8Array = new Uint8Array(utf8.length); // 创建 Uint8Array
|