@wiajs/core 0.1.15 → 0.1.19
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/dist/core.common.js +66 -35
- package/dist/core.common.min.js +2 -2
- package/dist/core.esm.js +65 -34
- package/dist/core.esm.min.js +2 -2
- package/dist/core.js +68 -37
- package/dist/core.min.js +2 -2
- package/package.json +2 -3
- package/util/tool.js +21 -14
- package/lib/bmap.js +0 -728
- package/lib/img/compress.js +0 -523
- package/lib/img/util.js +0 -392
package/lib/img/compress.js
DELETED
|
@@ -1,523 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fork from https://github.com/fengyuanchen/compressorjs
|
|
3
|
-
* use example:
|
|
4
|
-
|
|
5
|
-
import axios from 'axios';
|
|
6
|
-
import Compressor from 'compressorjs';
|
|
7
|
-
|
|
8
|
-
document.getElementById('file').addEventListener('change', (e) => {
|
|
9
|
-
const file = e.target.files[0];
|
|
10
|
-
|
|
11
|
-
if (!file) {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
new Compressor(file, {
|
|
16
|
-
quality: 0.6,
|
|
17
|
-
success(result) {
|
|
18
|
-
const formData = new FormData();
|
|
19
|
-
|
|
20
|
-
// The third parameter is required for server
|
|
21
|
-
formData.append('file', result, result.name);
|
|
22
|
-
|
|
23
|
-
// Send the compressed image file to server with XMLHttpRequest.
|
|
24
|
-
axios.post('/path/to/upload', formData).then(() => {
|
|
25
|
-
console.log('Upload success');
|
|
26
|
-
});
|
|
27
|
-
},
|
|
28
|
-
error(err) {
|
|
29
|
-
console.log(err.message);
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
import {
|
|
37
|
-
toBlob,
|
|
38
|
-
isBlob,
|
|
39
|
-
arrayBufferToDataURL,
|
|
40
|
-
imageTypeToExtension,
|
|
41
|
-
isImageType,
|
|
42
|
-
normalizeDecimalNumber,
|
|
43
|
-
parseOrientation,
|
|
44
|
-
resetAndGetOrientation,
|
|
45
|
-
} from './util';
|
|
46
|
-
|
|
47
|
-
const {ArrayBuffer, FileReader} = window;
|
|
48
|
-
const URL = window.URL || window.webkitURL;
|
|
49
|
-
const REGEXP_EXTENSION = /\.\w+$/;
|
|
50
|
-
const AnotherCompressor = window.Compressor;
|
|
51
|
-
|
|
52
|
-
const DEFAULTS = {
|
|
53
|
-
/**
|
|
54
|
-
* Indicates if output the original image instead of the compressed one
|
|
55
|
-
* when the size of the compressed image is greater than the original one's
|
|
56
|
-
* @type {boolean}
|
|
57
|
-
*/
|
|
58
|
-
strict: true,
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Indicates if read the image's Exif Orientation information,
|
|
62
|
-
* and then rotate or flip the image automatically.
|
|
63
|
-
* @type {boolean}
|
|
64
|
-
*/
|
|
65
|
-
checkOrientation: true,
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The max width of the output image.
|
|
69
|
-
* @type {number}
|
|
70
|
-
*/
|
|
71
|
-
maxWidth: Infinity,
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* The max height of the output image.
|
|
75
|
-
* @type {number}
|
|
76
|
-
*/
|
|
77
|
-
maxHeight: Infinity,
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* The min width of the output image.
|
|
81
|
-
* @type {number}
|
|
82
|
-
*/
|
|
83
|
-
minWidth: 0,
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* The min height of the output image.
|
|
87
|
-
* @type {number}
|
|
88
|
-
*/
|
|
89
|
-
minHeight: 0,
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* The width of the output image.
|
|
93
|
-
* If not specified, the natural width of the source image will be used.
|
|
94
|
-
* @type {number}
|
|
95
|
-
*/
|
|
96
|
-
width: undefined,
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* The height of the output image.
|
|
100
|
-
* If not specified, the natural height of the source image will be used.
|
|
101
|
-
* @type {number}
|
|
102
|
-
*/
|
|
103
|
-
height: undefined,
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* The quality of the output image.
|
|
107
|
-
* It must be a number between `0` and `1`,
|
|
108
|
-
* and only available for `image/jpeg` and `image/webp` images.
|
|
109
|
-
* Check out {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob canvas.toBlob}.
|
|
110
|
-
* @type {number}
|
|
111
|
-
*/
|
|
112
|
-
quality: 0.8,
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* The mime type of the output image.
|
|
116
|
-
* By default, the original mime type of the source image file will be used.
|
|
117
|
-
* @type {string}
|
|
118
|
-
*/
|
|
119
|
-
mimeType: 'auto',
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* PNG files over this value (5 MB by default) will be converted to JPEGs.
|
|
123
|
-
* To disable this, just set the value to `Infinity`.
|
|
124
|
-
* @type {number}
|
|
125
|
-
*/
|
|
126
|
-
convertSize: 5000000,
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* The hook function to execute before draw the image into the canvas for compression.
|
|
130
|
-
* @type {Function}
|
|
131
|
-
* @param {CanvasRenderingContext2D} context - The 2d rendering context of the canvas.
|
|
132
|
-
* @param {HTMLCanvasElement} canvas - The canvas for compression.
|
|
133
|
-
* @example
|
|
134
|
-
* function (context, canvas) {
|
|
135
|
-
* context.fillStyle = '#fff';
|
|
136
|
-
* }
|
|
137
|
-
*/
|
|
138
|
-
beforeDraw: null,
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* The hook function to execute after drew the image into the canvas for compression.
|
|
142
|
-
* @type {Function}
|
|
143
|
-
* @param {CanvasRenderingContext2D} context - The 2d rendering context of the canvas.
|
|
144
|
-
* @param {HTMLCanvasElement} canvas - The canvas for compression.
|
|
145
|
-
* @example
|
|
146
|
-
* function (context, canvas) {
|
|
147
|
-
* context.filter = 'grayscale(100%)';
|
|
148
|
-
* }
|
|
149
|
-
*/
|
|
150
|
-
drew: null,
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* The hook function to execute when success to compress the image.
|
|
154
|
-
* @type {Function}
|
|
155
|
-
* @param {File} file - The compressed image File object.
|
|
156
|
-
* @example
|
|
157
|
-
* function (file) {
|
|
158
|
-
* console.log(file);
|
|
159
|
-
* }
|
|
160
|
-
*/
|
|
161
|
-
success: null,
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* The hook function to execute when fail to compress the image.
|
|
165
|
-
* @type {Function}
|
|
166
|
-
* @param {Error} err - An Error object.
|
|
167
|
-
* @example
|
|
168
|
-
* function (err) {
|
|
169
|
-
* console.log(err.message);
|
|
170
|
-
* }
|
|
171
|
-
*/
|
|
172
|
-
error: null,
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Creates a new image compressor.
|
|
177
|
-
* @class
|
|
178
|
-
*/
|
|
179
|
-
export default class Compress {
|
|
180
|
-
/**
|
|
181
|
-
* The constructor of Compressor.
|
|
182
|
-
* @param {File|Blob} file - The target image file for compressing.
|
|
183
|
-
* @param {Object} [options] - The options for compressing.
|
|
184
|
-
*/
|
|
185
|
-
constructor(file, options) {
|
|
186
|
-
this.file = file;
|
|
187
|
-
this.image = new Image();
|
|
188
|
-
this.options = {
|
|
189
|
-
...DEFAULTS,
|
|
190
|
-
...options,
|
|
191
|
-
};
|
|
192
|
-
this.aborted = false;
|
|
193
|
-
this.result = null;
|
|
194
|
-
this.init();
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
init() {
|
|
198
|
-
const {file, options} = this;
|
|
199
|
-
|
|
200
|
-
if (!isBlob(file)) {
|
|
201
|
-
this.fail(new Error('The first argument must be a File or Blob object.'));
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const mimeType = file.type;
|
|
206
|
-
|
|
207
|
-
if (!isImageType(mimeType)) {
|
|
208
|
-
this.fail(
|
|
209
|
-
new Error('The first argument must be an image File or Blob object.')
|
|
210
|
-
);
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
if (!URL || !FileReader) {
|
|
215
|
-
this.fail(
|
|
216
|
-
new Error('The current browser does not support image compression.')
|
|
217
|
-
);
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (!ArrayBuffer) {
|
|
222
|
-
options.checkOrientation = false;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (URL && !options.checkOrientation) {
|
|
226
|
-
this.load({
|
|
227
|
-
url: URL.createObjectURL(file),
|
|
228
|
-
});
|
|
229
|
-
} else {
|
|
230
|
-
const reader = new FileReader();
|
|
231
|
-
const checkOrientation =
|
|
232
|
-
options.checkOrientation && mimeType === 'image/jpeg';
|
|
233
|
-
|
|
234
|
-
this.reader = reader;
|
|
235
|
-
reader.onload = ({target}) => {
|
|
236
|
-
const {result} = target;
|
|
237
|
-
const data = {};
|
|
238
|
-
|
|
239
|
-
if (checkOrientation) {
|
|
240
|
-
// Reset the orientation value to its default value 1
|
|
241
|
-
// as some iOS browsers will render image with its orientation
|
|
242
|
-
const orientation = resetAndGetOrientation(result);
|
|
243
|
-
|
|
244
|
-
if (orientation > 1 || !URL) {
|
|
245
|
-
// Generate a new URL which has the default orientation value
|
|
246
|
-
data.url = arrayBufferToDataURL(result, mimeType);
|
|
247
|
-
|
|
248
|
-
if (orientation > 1) {
|
|
249
|
-
Object.assign(data, parseOrientation(orientation));
|
|
250
|
-
}
|
|
251
|
-
} else {
|
|
252
|
-
data.url = URL.createObjectURL(file);
|
|
253
|
-
}
|
|
254
|
-
} else {
|
|
255
|
-
data.url = result;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
this.load(data);
|
|
259
|
-
};
|
|
260
|
-
reader.onabort = () => {
|
|
261
|
-
this.fail(new Error('Aborted to read the image with FileReader.'));
|
|
262
|
-
};
|
|
263
|
-
reader.onerror = () => {
|
|
264
|
-
this.fail(new Error('Failed to read the image with FileReader.'));
|
|
265
|
-
};
|
|
266
|
-
reader.onloadend = () => {
|
|
267
|
-
this.reader = null;
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
if (checkOrientation) {
|
|
271
|
-
reader.readAsArrayBuffer(file);
|
|
272
|
-
} else {
|
|
273
|
-
reader.readAsDataURL(file);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
load(data) {
|
|
279
|
-
const {file, image} = this;
|
|
280
|
-
|
|
281
|
-
image.onload = () => {
|
|
282
|
-
this.draw({
|
|
283
|
-
...data,
|
|
284
|
-
naturalWidth: image.naturalWidth,
|
|
285
|
-
naturalHeight: image.naturalHeight,
|
|
286
|
-
});
|
|
287
|
-
};
|
|
288
|
-
image.onabort = () => {
|
|
289
|
-
this.fail(new Error('Aborted to load the image.'));
|
|
290
|
-
};
|
|
291
|
-
image.onerror = () => {
|
|
292
|
-
this.fail(new Error('Failed to load the image.'));
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
// Match all browsers that use WebKit as the layout engine in iOS devices,
|
|
296
|
-
// such as Safari for iOS, Chrome for iOS, and in-app browsers.
|
|
297
|
-
if (
|
|
298
|
-
window.navigator &&
|
|
299
|
-
/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(window.navigator.userAgent)
|
|
300
|
-
) {
|
|
301
|
-
// Fix the `The operation is insecure` error (#57)
|
|
302
|
-
image.crossOrigin = 'anonymous';
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
image.alt = file.name;
|
|
306
|
-
image.src = data.url;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
draw({naturalWidth, naturalHeight, rotate = 0, scaleX = 1, scaleY = 1}) {
|
|
310
|
-
const {file, image, options} = this;
|
|
311
|
-
const canvas = document.createElement('canvas');
|
|
312
|
-
const context = canvas.getContext('2d');
|
|
313
|
-
const aspectRatio = naturalWidth / naturalHeight;
|
|
314
|
-
const is90DegreesRotated = Math.abs(rotate) % 180 === 90;
|
|
315
|
-
let maxWidth = Math.max(options.maxWidth, 0) || Infinity;
|
|
316
|
-
let maxHeight = Math.max(options.maxHeight, 0) || Infinity;
|
|
317
|
-
let minWidth = Math.max(options.minWidth, 0) || 0;
|
|
318
|
-
let minHeight = Math.max(options.minHeight, 0) || 0;
|
|
319
|
-
let width = Math.max(options.width, 0) || naturalWidth;
|
|
320
|
-
let height = Math.max(options.height, 0) || naturalHeight;
|
|
321
|
-
|
|
322
|
-
if (is90DegreesRotated) {
|
|
323
|
-
[maxWidth, maxHeight] = [maxHeight, maxWidth];
|
|
324
|
-
[minWidth, minHeight] = [minHeight, minWidth];
|
|
325
|
-
[width, height] = [height, width];
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
if (maxWidth < Infinity && maxHeight < Infinity) {
|
|
329
|
-
if (maxHeight * aspectRatio > maxWidth) {
|
|
330
|
-
maxHeight = maxWidth / aspectRatio;
|
|
331
|
-
} else {
|
|
332
|
-
maxWidth = maxHeight * aspectRatio;
|
|
333
|
-
}
|
|
334
|
-
} else if (maxWidth < Infinity) {
|
|
335
|
-
maxHeight = maxWidth / aspectRatio;
|
|
336
|
-
} else if (maxHeight < Infinity) {
|
|
337
|
-
maxWidth = maxHeight * aspectRatio;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if (minWidth > 0 && minHeight > 0) {
|
|
341
|
-
if (minHeight * aspectRatio > minWidth) {
|
|
342
|
-
minHeight = minWidth / aspectRatio;
|
|
343
|
-
} else {
|
|
344
|
-
minWidth = minHeight * aspectRatio;
|
|
345
|
-
}
|
|
346
|
-
} else if (minWidth > 0) {
|
|
347
|
-
minHeight = minWidth / aspectRatio;
|
|
348
|
-
} else if (minHeight > 0) {
|
|
349
|
-
minWidth = minHeight * aspectRatio;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
if (height * aspectRatio > width) {
|
|
353
|
-
height = width / aspectRatio;
|
|
354
|
-
} else {
|
|
355
|
-
width = height * aspectRatio;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
width = Math.floor(
|
|
359
|
-
normalizeDecimalNumber(Math.min(Math.max(width, minWidth), maxWidth))
|
|
360
|
-
);
|
|
361
|
-
height = Math.floor(
|
|
362
|
-
normalizeDecimalNumber(Math.min(Math.max(height, minHeight), maxHeight))
|
|
363
|
-
);
|
|
364
|
-
|
|
365
|
-
const destX = -width / 2;
|
|
366
|
-
const destY = -height / 2;
|
|
367
|
-
const destWidth = width;
|
|
368
|
-
const destHeight = height;
|
|
369
|
-
|
|
370
|
-
if (is90DegreesRotated) {
|
|
371
|
-
[width, height] = [height, width];
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
canvas.width = width;
|
|
375
|
-
canvas.height = height;
|
|
376
|
-
|
|
377
|
-
if (!isImageType(options.mimeType)) {
|
|
378
|
-
options.mimeType = file.type;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
let fillStyle = 'transparent';
|
|
382
|
-
|
|
383
|
-
// Converts PNG files over the `convertSize` to JPEGs.
|
|
384
|
-
if (file.size > options.convertSize && options.mimeType === 'image/png') {
|
|
385
|
-
fillStyle = '#fff';
|
|
386
|
-
options.mimeType = 'image/jpeg';
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
// Override the default fill color (#000, black)
|
|
390
|
-
context.fillStyle = fillStyle;
|
|
391
|
-
context.fillRect(0, 0, width, height);
|
|
392
|
-
|
|
393
|
-
if (options.beforeDraw) {
|
|
394
|
-
options.beforeDraw.call(this, context, canvas);
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
if (this.aborted) {
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
context.save();
|
|
402
|
-
context.translate(width / 2, height / 2);
|
|
403
|
-
context.rotate((rotate * Math.PI) / 180);
|
|
404
|
-
context.scale(scaleX, scaleY);
|
|
405
|
-
context.drawImage(image, destX, destY, destWidth, destHeight);
|
|
406
|
-
context.restore();
|
|
407
|
-
|
|
408
|
-
if (options.drew) {
|
|
409
|
-
options.drew.call(this, context, canvas);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
if (this.aborted) {
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
const done = result => {
|
|
417
|
-
if (!this.aborted) {
|
|
418
|
-
this.done({
|
|
419
|
-
naturalWidth,
|
|
420
|
-
naturalHeight,
|
|
421
|
-
result,
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
|
|
426
|
-
// first use canvas.toBlob
|
|
427
|
-
if (canvas.toBlob) {
|
|
428
|
-
canvas.toBlob(done, options.mimeType, options.quality);
|
|
429
|
-
} else {
|
|
430
|
-
done(toBlob(canvas.toDataURL(options.mimeType, options.quality)));
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
done({naturalWidth, naturalHeight, result}) {
|
|
435
|
-
const {file, image, options} = this;
|
|
436
|
-
|
|
437
|
-
if (URL && !options.checkOrientation) {
|
|
438
|
-
URL.revokeObjectURL(image.src);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
if (result) {
|
|
442
|
-
// Returns original file if the result is greater than it and without size related options
|
|
443
|
-
if (
|
|
444
|
-
options.strict &&
|
|
445
|
-
result.size > file.size &&
|
|
446
|
-
options.mimeType === file.type &&
|
|
447
|
-
!(
|
|
448
|
-
options.width > naturalWidth ||
|
|
449
|
-
options.height > naturalHeight ||
|
|
450
|
-
options.minWidth > naturalWidth ||
|
|
451
|
-
options.minHeight > naturalHeight
|
|
452
|
-
)
|
|
453
|
-
) {
|
|
454
|
-
result = file;
|
|
455
|
-
} else {
|
|
456
|
-
const date = new Date();
|
|
457
|
-
|
|
458
|
-
result.lastModified = date.getTime();
|
|
459
|
-
result.lastModifiedDate = date;
|
|
460
|
-
result.name = file.name;
|
|
461
|
-
|
|
462
|
-
// Convert the extension to match its type
|
|
463
|
-
if (result.name && result.type !== file.type) {
|
|
464
|
-
result.name = result.name.replace(
|
|
465
|
-
REGEXP_EXTENSION,
|
|
466
|
-
imageTypeToExtension(result.type)
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
} else {
|
|
471
|
-
// Returns original file if the result is null in some cases.
|
|
472
|
-
result = file;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
this.result = result;
|
|
476
|
-
|
|
477
|
-
if (options.success) {
|
|
478
|
-
options.success.call(this, result);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
fail(err) {
|
|
483
|
-
const {options} = this;
|
|
484
|
-
|
|
485
|
-
if (options.error) {
|
|
486
|
-
options.error.call(this, err);
|
|
487
|
-
} else {
|
|
488
|
-
throw err;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
abort() {
|
|
493
|
-
if (!this.aborted) {
|
|
494
|
-
this.aborted = true;
|
|
495
|
-
|
|
496
|
-
if (this.reader) {
|
|
497
|
-
this.reader.abort();
|
|
498
|
-
} else if (!this.image.complete) {
|
|
499
|
-
this.image.onload = null;
|
|
500
|
-
this.image.onabort();
|
|
501
|
-
} else {
|
|
502
|
-
this.fail(new Error('The compression process has been aborted.'));
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
/**
|
|
508
|
-
* Get the no conflict compressor class.
|
|
509
|
-
* @returns {Compressor} The compressor class.
|
|
510
|
-
*/
|
|
511
|
-
static noConflict() {
|
|
512
|
-
window.Compress = AnotherCompressor;
|
|
513
|
-
return Compress;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
/**
|
|
517
|
-
* Change the default options.
|
|
518
|
-
* @param {Object} options - The new default options.
|
|
519
|
-
*/
|
|
520
|
-
static setDefaults(options) {
|
|
521
|
-
Object.assign(DEFAULTS, options);
|
|
522
|
-
}
|
|
523
|
-
}
|