cropper_rails 1.1.4 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CODE_OF_CONDUCT.md +2 -1
- data/CONTRIBUTING.md +1 -1
- data/README.md +3 -3
- data/VERSIONS.md +2 -0
- data/cropper_rails.gemspec +3 -3
- data/lib/cropper_rails/version.rb +2 -2
- data/vendor/assets/javascripts/cropper.js +338 -704
- data/vendor/assets/stylesheets/cropper.css +134 -129
- metadata +7 -7
@@ -1,41 +1,54 @@
|
|
1
1
|
/*!
|
2
|
-
* Cropper.js v1.5.
|
2
|
+
* Cropper.js v1.5.13
|
3
3
|
* https://fengyuanchen.github.io/cropperjs
|
4
4
|
*
|
5
5
|
* Copyright 2015-present Chen Fengyuan
|
6
6
|
* Released under the MIT license
|
7
7
|
*
|
8
|
-
* Date:
|
8
|
+
* Date: 2022-11-20T05:30:46.114Z
|
9
9
|
*/
|
10
10
|
|
11
11
|
(function (global, factory) {
|
12
12
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
13
13
|
typeof define === 'function' && define.amd ? define(factory) :
|
14
14
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Cropper = factory());
|
15
|
-
}(this, (function () { 'use strict';
|
15
|
+
})(this, (function () { 'use strict';
|
16
16
|
|
17
|
+
function ownKeys(object, enumerableOnly) {
|
18
|
+
var keys = Object.keys(object);
|
19
|
+
if (Object.getOwnPropertySymbols) {
|
20
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
21
|
+
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
22
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
23
|
+
})), keys.push.apply(keys, symbols);
|
24
|
+
}
|
25
|
+
return keys;
|
26
|
+
}
|
27
|
+
function _objectSpread2(target) {
|
28
|
+
for (var i = 1; i < arguments.length; i++) {
|
29
|
+
var source = null != arguments[i] ? arguments[i] : {};
|
30
|
+
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
31
|
+
_defineProperty(target, key, source[key]);
|
32
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
33
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
34
|
+
});
|
35
|
+
}
|
36
|
+
return target;
|
37
|
+
}
|
17
38
|
function _typeof(obj) {
|
18
39
|
"@babel/helpers - typeof";
|
19
40
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
}
|
25
|
-
_typeof = function (obj) {
|
26
|
-
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
27
|
-
};
|
28
|
-
}
|
29
|
-
|
30
|
-
return _typeof(obj);
|
41
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
|
42
|
+
return typeof obj;
|
43
|
+
} : function (obj) {
|
44
|
+
return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
45
|
+
}, _typeof(obj);
|
31
46
|
}
|
32
|
-
|
33
47
|
function _classCallCheck(instance, Constructor) {
|
34
48
|
if (!(instance instanceof Constructor)) {
|
35
49
|
throw new TypeError("Cannot call a class as a function");
|
36
50
|
}
|
37
51
|
}
|
38
|
-
|
39
52
|
function _defineProperties(target, props) {
|
40
53
|
for (var i = 0; i < props.length; i++) {
|
41
54
|
var descriptor = props[i];
|
@@ -45,13 +58,14 @@
|
|
45
58
|
Object.defineProperty(target, descriptor.key, descriptor);
|
46
59
|
}
|
47
60
|
}
|
48
|
-
|
49
61
|
function _createClass(Constructor, protoProps, staticProps) {
|
50
62
|
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
51
63
|
if (staticProps) _defineProperties(Constructor, staticProps);
|
64
|
+
Object.defineProperty(Constructor, "prototype", {
|
65
|
+
writable: false
|
66
|
+
});
|
52
67
|
return Constructor;
|
53
68
|
}
|
54
|
-
|
55
69
|
function _defineProperty(obj, key, value) {
|
56
70
|
if (key in obj) {
|
57
71
|
Object.defineProperty(obj, key, {
|
@@ -63,56 +77,17 @@
|
|
63
77
|
} else {
|
64
78
|
obj[key] = value;
|
65
79
|
}
|
66
|
-
|
67
80
|
return obj;
|
68
81
|
}
|
69
|
-
|
70
|
-
function ownKeys(object, enumerableOnly) {
|
71
|
-
var keys = Object.keys(object);
|
72
|
-
|
73
|
-
if (Object.getOwnPropertySymbols) {
|
74
|
-
var symbols = Object.getOwnPropertySymbols(object);
|
75
|
-
if (enumerableOnly) symbols = symbols.filter(function (sym) {
|
76
|
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
77
|
-
});
|
78
|
-
keys.push.apply(keys, symbols);
|
79
|
-
}
|
80
|
-
|
81
|
-
return keys;
|
82
|
-
}
|
83
|
-
|
84
|
-
function _objectSpread2(target) {
|
85
|
-
for (var i = 1; i < arguments.length; i++) {
|
86
|
-
var source = arguments[i] != null ? arguments[i] : {};
|
87
|
-
|
88
|
-
if (i % 2) {
|
89
|
-
ownKeys(Object(source), true).forEach(function (key) {
|
90
|
-
_defineProperty(target, key, source[key]);
|
91
|
-
});
|
92
|
-
} else if (Object.getOwnPropertyDescriptors) {
|
93
|
-
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
94
|
-
} else {
|
95
|
-
ownKeys(Object(source)).forEach(function (key) {
|
96
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
97
|
-
});
|
98
|
-
}
|
99
|
-
}
|
100
|
-
|
101
|
-
return target;
|
102
|
-
}
|
103
|
-
|
104
82
|
function _toConsumableArray(arr) {
|
105
83
|
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
106
84
|
}
|
107
|
-
|
108
85
|
function _arrayWithoutHoles(arr) {
|
109
86
|
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
110
87
|
}
|
111
|
-
|
112
88
|
function _iterableToArray(iter) {
|
113
|
-
if (typeof Symbol !== "undefined" && Symbol.iterator
|
89
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
114
90
|
}
|
115
|
-
|
116
91
|
function _unsupportedIterableToArray(o, minLen) {
|
117
92
|
if (!o) return;
|
118
93
|
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
@@ -121,15 +96,11 @@
|
|
121
96
|
if (n === "Map" || n === "Set") return Array.from(o);
|
122
97
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
123
98
|
}
|
124
|
-
|
125
99
|
function _arrayLikeToArray(arr, len) {
|
126
100
|
if (len == null || len > arr.length) len = arr.length;
|
127
|
-
|
128
101
|
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
129
|
-
|
130
102
|
return arr2;
|
131
103
|
}
|
132
|
-
|
133
104
|
function _nonIterableSpread() {
|
134
105
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
135
106
|
}
|
@@ -138,8 +109,9 @@
|
|
138
109
|
var WINDOW = IS_BROWSER ? window : {};
|
139
110
|
var IS_TOUCH_DEVICE = IS_BROWSER && WINDOW.document.documentElement ? 'ontouchstart' in WINDOW.document.documentElement : false;
|
140
111
|
var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;
|
141
|
-
var NAMESPACE = 'cropper';
|
112
|
+
var NAMESPACE = 'cropper';
|
142
113
|
|
114
|
+
// Actions
|
143
115
|
var ACTION_ALL = 'all';
|
144
116
|
var ACTION_CROP = 'crop';
|
145
117
|
var ACTION_MOVE = 'move';
|
@@ -151,23 +123,27 @@
|
|
151
123
|
var ACTION_NORTH_EAST = 'ne';
|
152
124
|
var ACTION_NORTH_WEST = 'nw';
|
153
125
|
var ACTION_SOUTH_EAST = 'se';
|
154
|
-
var ACTION_SOUTH_WEST = 'sw';
|
126
|
+
var ACTION_SOUTH_WEST = 'sw';
|
155
127
|
|
128
|
+
// Classes
|
156
129
|
var CLASS_CROP = "".concat(NAMESPACE, "-crop");
|
157
130
|
var CLASS_DISABLED = "".concat(NAMESPACE, "-disabled");
|
158
131
|
var CLASS_HIDDEN = "".concat(NAMESPACE, "-hidden");
|
159
132
|
var CLASS_HIDE = "".concat(NAMESPACE, "-hide");
|
160
133
|
var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");
|
161
134
|
var CLASS_MODAL = "".concat(NAMESPACE, "-modal");
|
162
|
-
var CLASS_MOVE = "".concat(NAMESPACE, "-move");
|
135
|
+
var CLASS_MOVE = "".concat(NAMESPACE, "-move");
|
163
136
|
|
137
|
+
// Data keys
|
164
138
|
var DATA_ACTION = "".concat(NAMESPACE, "Action");
|
165
|
-
var DATA_PREVIEW = "".concat(NAMESPACE, "Preview");
|
139
|
+
var DATA_PREVIEW = "".concat(NAMESPACE, "Preview");
|
166
140
|
|
141
|
+
// Drag modes
|
167
142
|
var DRAG_MODE_CROP = 'crop';
|
168
143
|
var DRAG_MODE_MOVE = 'move';
|
169
|
-
var DRAG_MODE_NONE = 'none';
|
144
|
+
var DRAG_MODE_NONE = 'none';
|
170
145
|
|
146
|
+
// Events
|
171
147
|
var EVENT_CROP = 'crop';
|
172
148
|
var EVENT_CROP_END = 'cropend';
|
173
149
|
var EVENT_CROP_MOVE = 'cropmove';
|
@@ -182,16 +158,19 @@
|
|
182
158
|
var EVENT_READY = 'ready';
|
183
159
|
var EVENT_RESIZE = 'resize';
|
184
160
|
var EVENT_WHEEL = 'wheel';
|
185
|
-
var EVENT_ZOOM = 'zoom';
|
161
|
+
var EVENT_ZOOM = 'zoom';
|
186
162
|
|
187
|
-
|
163
|
+
// Mime types
|
164
|
+
var MIME_TYPE_JPEG = 'image/jpeg';
|
188
165
|
|
166
|
+
// RegExps
|
189
167
|
var REGEXP_ACTIONS = /^e|w|s|n|se|sw|ne|nw|all|crop|move|zoom$/;
|
190
168
|
var REGEXP_DATA_URL = /^data:/;
|
191
169
|
var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/;
|
192
|
-
var REGEXP_TAG_NAME = /^img|canvas$/i;
|
193
|
-
// Inspired by the default width and height of a canvas element.
|
170
|
+
var REGEXP_TAG_NAME = /^img|canvas$/i;
|
194
171
|
|
172
|
+
// Misc
|
173
|
+
// Inspired by the default width and height of a canvas element.
|
195
174
|
var MIN_CONTAINER_WIDTH = 200;
|
196
175
|
var MIN_CONTAINER_HEIGHT = 100;
|
197
176
|
|
@@ -199,9 +178,11 @@
|
|
199
178
|
// Define the view mode of the cropper
|
200
179
|
viewMode: 0,
|
201
180
|
// 0, 1, 2, 3
|
181
|
+
|
202
182
|
// Define the dragging mode of the cropper
|
203
183
|
dragMode: DRAG_MODE_CROP,
|
204
184
|
// 'crop', 'move' or 'none'
|
185
|
+
|
205
186
|
// Define the initial aspect ratio of the crop box
|
206
187
|
initialAspectRatio: NaN,
|
207
188
|
// Define the aspect ratio of the crop box
|
@@ -273,56 +254,54 @@
|
|
273
254
|
/**
|
274
255
|
* Check if the given value is not a number.
|
275
256
|
*/
|
276
|
-
|
277
257
|
var isNaN = Number.isNaN || WINDOW.isNaN;
|
258
|
+
|
278
259
|
/**
|
279
260
|
* Check if the given value is a number.
|
280
261
|
* @param {*} value - The value to check.
|
281
262
|
* @returns {boolean} Returns `true` if the given value is a number, else `false`.
|
282
263
|
*/
|
283
|
-
|
284
264
|
function isNumber(value) {
|
285
265
|
return typeof value === 'number' && !isNaN(value);
|
286
266
|
}
|
267
|
+
|
287
268
|
/**
|
288
269
|
* Check if the given value is a positive number.
|
289
270
|
* @param {*} value - The value to check.
|
290
271
|
* @returns {boolean} Returns `true` if the given value is a positive number, else `false`.
|
291
272
|
*/
|
292
|
-
|
293
273
|
var isPositiveNumber = function isPositiveNumber(value) {
|
294
274
|
return value > 0 && value < Infinity;
|
295
275
|
};
|
276
|
+
|
296
277
|
/**
|
297
278
|
* Check if the given value is undefined.
|
298
279
|
* @param {*} value - The value to check.
|
299
280
|
* @returns {boolean} Returns `true` if the given value is undefined, else `false`.
|
300
281
|
*/
|
301
|
-
|
302
282
|
function isUndefined(value) {
|
303
283
|
return typeof value === 'undefined';
|
304
284
|
}
|
285
|
+
|
305
286
|
/**
|
306
287
|
* Check if the given value is an object.
|
307
288
|
* @param {*} value - The value to check.
|
308
289
|
* @returns {boolean} Returns `true` if the given value is an object, else `false`.
|
309
290
|
*/
|
310
|
-
|
311
291
|
function isObject(value) {
|
312
292
|
return _typeof(value) === 'object' && value !== null;
|
313
293
|
}
|
314
294
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
295
|
+
|
315
296
|
/**
|
316
297
|
* Check if the given value is a plain object.
|
317
298
|
* @param {*} value - The value to check.
|
318
299
|
* @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
|
319
300
|
*/
|
320
|
-
|
321
301
|
function isPlainObject(value) {
|
322
302
|
if (!isObject(value)) {
|
323
303
|
return false;
|
324
304
|
}
|
325
|
-
|
326
305
|
try {
|
327
306
|
var _constructor = value.constructor;
|
328
307
|
var prototype = _constructor.prototype;
|
@@ -331,61 +310,57 @@
|
|
331
310
|
return false;
|
332
311
|
}
|
333
312
|
}
|
313
|
+
|
334
314
|
/**
|
335
315
|
* Check if the given value is a function.
|
336
316
|
* @param {*} value - The value to check.
|
337
317
|
* @returns {boolean} Returns `true` if the given value is a function, else `false`.
|
338
318
|
*/
|
339
|
-
|
340
319
|
function isFunction(value) {
|
341
320
|
return typeof value === 'function';
|
342
321
|
}
|
343
322
|
var slice = Array.prototype.slice;
|
323
|
+
|
344
324
|
/**
|
345
325
|
* Convert array-like or iterable object to an array.
|
346
326
|
* @param {*} value - The value to convert.
|
347
327
|
* @returns {Array} Returns a new array.
|
348
328
|
*/
|
349
|
-
|
350
329
|
function toArray(value) {
|
351
330
|
return Array.from ? Array.from(value) : slice.call(value);
|
352
331
|
}
|
332
|
+
|
353
333
|
/**
|
354
334
|
* Iterate the given data.
|
355
335
|
* @param {*} data - The data to iterate.
|
356
336
|
* @param {Function} callback - The process function for each element.
|
357
337
|
* @returns {*} The original data.
|
358
338
|
*/
|
359
|
-
|
360
339
|
function forEach(data, callback) {
|
361
340
|
if (data && isFunction(callback)) {
|
362
|
-
if (Array.isArray(data) || isNumber(data.length)
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
});
|
368
|
-
} else if (isObject(data)) {
|
341
|
+
if (Array.isArray(data) || isNumber(data.length) /* array-like */) {
|
342
|
+
toArray(data).forEach(function (value, key) {
|
343
|
+
callback.call(data, value, key, data);
|
344
|
+
});
|
345
|
+
} else if (isObject(data)) {
|
369
346
|
Object.keys(data).forEach(function (key) {
|
370
347
|
callback.call(data, data[key], key, data);
|
371
348
|
});
|
372
349
|
}
|
373
350
|
}
|
374
|
-
|
375
351
|
return data;
|
376
352
|
}
|
353
|
+
|
377
354
|
/**
|
378
355
|
* Extend the given object.
|
379
356
|
* @param {*} target - The target object to extend.
|
380
357
|
* @param {*} args - The rest objects for merging to the target object.
|
381
358
|
* @returns {Object} The extended object.
|
382
359
|
*/
|
383
|
-
|
384
360
|
var assign = Object.assign || function assign(target) {
|
385
361
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
386
362
|
args[_key - 1] = arguments[_key];
|
387
363
|
}
|
388
|
-
|
389
364
|
if (isObject(target) && args.length > 0) {
|
390
365
|
args.forEach(function (arg) {
|
391
366
|
if (isObject(arg)) {
|
@@ -395,10 +370,10 @@
|
|
395
370
|
}
|
396
371
|
});
|
397
372
|
}
|
398
|
-
|
399
373
|
return target;
|
400
374
|
};
|
401
375
|
var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
|
376
|
+
|
402
377
|
/**
|
403
378
|
* Normalize decimal number.
|
404
379
|
* Check out {@link https://0.30000000000000004.com/}
|
@@ -406,116 +381,106 @@
|
|
406
381
|
* @param {number} [times=100000000000] - The times for normalizing.
|
407
382
|
* @returns {number} Returns the normalized number.
|
408
383
|
*/
|
409
|
-
|
410
384
|
function normalizeDecimalNumber(value) {
|
411
385
|
var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
|
412
386
|
return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
|
413
387
|
}
|
414
388
|
var REGEXP_SUFFIX = /^width|height|left|top|marginLeft|marginTop$/;
|
389
|
+
|
415
390
|
/**
|
416
391
|
* Apply styles to the given element.
|
417
392
|
* @param {Element} element - The target element.
|
418
393
|
* @param {Object} styles - The styles for applying.
|
419
394
|
*/
|
420
|
-
|
421
395
|
function setStyle(element, styles) {
|
422
396
|
var style = element.style;
|
423
397
|
forEach(styles, function (value, property) {
|
424
398
|
if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
|
425
399
|
value = "".concat(value, "px");
|
426
400
|
}
|
427
|
-
|
428
401
|
style[property] = value;
|
429
402
|
});
|
430
403
|
}
|
404
|
+
|
431
405
|
/**
|
432
406
|
* Check if the given element has a special class.
|
433
407
|
* @param {Element} element - The element to check.
|
434
408
|
* @param {string} value - The class to search.
|
435
409
|
* @returns {boolean} Returns `true` if the special class was found.
|
436
410
|
*/
|
437
|
-
|
438
411
|
function hasClass(element, value) {
|
439
412
|
return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
|
440
413
|
}
|
414
|
+
|
441
415
|
/**
|
442
416
|
* Add classes to the given element.
|
443
417
|
* @param {Element} element - The target element.
|
444
418
|
* @param {string} value - The classes to be added.
|
445
419
|
*/
|
446
|
-
|
447
420
|
function addClass(element, value) {
|
448
421
|
if (!value) {
|
449
422
|
return;
|
450
423
|
}
|
451
|
-
|
452
424
|
if (isNumber(element.length)) {
|
453
425
|
forEach(element, function (elem) {
|
454
426
|
addClass(elem, value);
|
455
427
|
});
|
456
428
|
return;
|
457
429
|
}
|
458
|
-
|
459
430
|
if (element.classList) {
|
460
431
|
element.classList.add(value);
|
461
432
|
return;
|
462
433
|
}
|
463
|
-
|
464
434
|
var className = element.className.trim();
|
465
|
-
|
466
435
|
if (!className) {
|
467
436
|
element.className = value;
|
468
437
|
} else if (className.indexOf(value) < 0) {
|
469
438
|
element.className = "".concat(className, " ").concat(value);
|
470
439
|
}
|
471
440
|
}
|
441
|
+
|
472
442
|
/**
|
473
443
|
* Remove classes from the given element.
|
474
444
|
* @param {Element} element - The target element.
|
475
445
|
* @param {string} value - The classes to be removed.
|
476
446
|
*/
|
477
|
-
|
478
447
|
function removeClass(element, value) {
|
479
448
|
if (!value) {
|
480
449
|
return;
|
481
450
|
}
|
482
|
-
|
483
451
|
if (isNumber(element.length)) {
|
484
452
|
forEach(element, function (elem) {
|
485
453
|
removeClass(elem, value);
|
486
454
|
});
|
487
455
|
return;
|
488
456
|
}
|
489
|
-
|
490
457
|
if (element.classList) {
|
491
458
|
element.classList.remove(value);
|
492
459
|
return;
|
493
460
|
}
|
494
|
-
|
495
461
|
if (element.className.indexOf(value) >= 0) {
|
496
462
|
element.className = element.className.replace(value, '');
|
497
463
|
}
|
498
464
|
}
|
465
|
+
|
499
466
|
/**
|
500
467
|
* Add or remove classes from the given element.
|
501
468
|
* @param {Element} element - The target element.
|
502
469
|
* @param {string} value - The classes to be toggled.
|
503
470
|
* @param {boolean} added - Add only.
|
504
471
|
*/
|
505
|
-
|
506
472
|
function toggleClass(element, value, added) {
|
507
473
|
if (!value) {
|
508
474
|
return;
|
509
475
|
}
|
510
|
-
|
511
476
|
if (isNumber(element.length)) {
|
512
477
|
forEach(element, function (elem) {
|
513
478
|
toggleClass(elem, value, added);
|
514
479
|
});
|
515
480
|
return;
|
516
|
-
}
|
517
|
-
|
481
|
+
}
|
518
482
|
|
483
|
+
// IE10-11 doesn't support the second parameter of `classList.toggle`
|
519
484
|
if (added) {
|
520
485
|
addClass(element, value);
|
521
486
|
} else {
|
@@ -523,40 +488,38 @@
|
|
523
488
|
}
|
524
489
|
}
|
525
490
|
var REGEXP_CAMEL_CASE = /([a-z\d])([A-Z])/g;
|
491
|
+
|
526
492
|
/**
|
527
493
|
* Transform the given string from camelCase to kebab-case
|
528
494
|
* @param {string} value - The value to transform.
|
529
495
|
* @returns {string} The transformed value.
|
530
496
|
*/
|
531
|
-
|
532
497
|
function toParamCase(value) {
|
533
498
|
return value.replace(REGEXP_CAMEL_CASE, '$1-$2').toLowerCase();
|
534
499
|
}
|
500
|
+
|
535
501
|
/**
|
536
502
|
* Get data from the given element.
|
537
503
|
* @param {Element} element - The target element.
|
538
504
|
* @param {string} name - The data key to get.
|
539
505
|
* @returns {string} The data value.
|
540
506
|
*/
|
541
|
-
|
542
507
|
function getData(element, name) {
|
543
508
|
if (isObject(element[name])) {
|
544
509
|
return element[name];
|
545
510
|
}
|
546
|
-
|
547
511
|
if (element.dataset) {
|
548
512
|
return element.dataset[name];
|
549
513
|
}
|
550
|
-
|
551
514
|
return element.getAttribute("data-".concat(toParamCase(name)));
|
552
515
|
}
|
516
|
+
|
553
517
|
/**
|
554
518
|
* Set data to the given element.
|
555
519
|
* @param {Element} element - The target element.
|
556
520
|
* @param {string} name - The data key to set.
|
557
521
|
* @param {string} data - The data value.
|
558
522
|
*/
|
559
|
-
|
560
523
|
function setData(element, name, data) {
|
561
524
|
if (isObject(data)) {
|
562
525
|
element[name] = data;
|
@@ -566,12 +529,12 @@
|
|
566
529
|
element.setAttribute("data-".concat(toParamCase(name)), data);
|
567
530
|
}
|
568
531
|
}
|
532
|
+
|
569
533
|
/**
|
570
534
|
* Remove data from the given element.
|
571
535
|
* @param {Element} element - The target element.
|
572
536
|
* @param {string} name - The data key to remove.
|
573
537
|
*/
|
574
|
-
|
575
538
|
function removeData(element, name) {
|
576
539
|
if (isObject(element[name])) {
|
577
540
|
try {
|
@@ -591,21 +554,16 @@
|
|
591
554
|
}
|
592
555
|
}
|
593
556
|
var REGEXP_SPACES = /\s\s*/;
|
594
|
-
|
595
557
|
var onceSupported = function () {
|
596
558
|
var supported = false;
|
597
|
-
|
598
559
|
if (IS_BROWSER) {
|
599
560
|
var once = false;
|
600
|
-
|
601
561
|
var listener = function listener() {};
|
602
|
-
|
603
562
|
var options = Object.defineProperty({}, 'once', {
|
604
563
|
get: function get() {
|
605
564
|
supported = true;
|
606
565
|
return once;
|
607
566
|
},
|
608
|
-
|
609
567
|
/**
|
610
568
|
* This setter can fix a `TypeError` in strict mode
|
611
569
|
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
|
@@ -618,9 +576,9 @@
|
|
618
576
|
WINDOW.addEventListener('test', listener, options);
|
619
577
|
WINDOW.removeEventListener('test', listener, options);
|
620
578
|
}
|
621
|
-
|
622
579
|
return supported;
|
623
580
|
}();
|
581
|
+
|
624
582
|
/**
|
625
583
|
* Remove event listener from the target element.
|
626
584
|
* @param {Element} element - The event target.
|
@@ -628,32 +586,27 @@
|
|
628
586
|
* @param {Function} listener - The event listener.
|
629
587
|
* @param {Object} options - The event options.
|
630
588
|
*/
|
631
|
-
|
632
|
-
|
633
589
|
function removeListener(element, type, listener) {
|
634
590
|
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
635
591
|
var handler = listener;
|
636
592
|
type.trim().split(REGEXP_SPACES).forEach(function (event) {
|
637
593
|
if (!onceSupported) {
|
638
594
|
var listeners = element.listeners;
|
639
|
-
|
640
595
|
if (listeners && listeners[event] && listeners[event][listener]) {
|
641
596
|
handler = listeners[event][listener];
|
642
597
|
delete listeners[event][listener];
|
643
|
-
|
644
598
|
if (Object.keys(listeners[event]).length === 0) {
|
645
599
|
delete listeners[event];
|
646
600
|
}
|
647
|
-
|
648
601
|
if (Object.keys(listeners).length === 0) {
|
649
602
|
delete element.listeners;
|
650
603
|
}
|
651
604
|
}
|
652
605
|
}
|
653
|
-
|
654
606
|
element.removeEventListener(event, handler, options);
|
655
607
|
});
|
656
608
|
}
|
609
|
+
|
657
610
|
/**
|
658
611
|
* Add event listener to the target element.
|
659
612
|
* @param {Element} element - The event target.
|
@@ -661,41 +614,34 @@
|
|
661
614
|
* @param {Function} listener - The event listener.
|
662
615
|
* @param {Object} options - The event options.
|
663
616
|
*/
|
664
|
-
|
665
617
|
function addListener(element, type, listener) {
|
666
618
|
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
667
619
|
var _handler = listener;
|
668
620
|
type.trim().split(REGEXP_SPACES).forEach(function (event) {
|
669
621
|
if (options.once && !onceSupported) {
|
670
622
|
var _element$listeners = element.listeners,
|
671
|
-
|
672
|
-
|
623
|
+
listeners = _element$listeners === void 0 ? {} : _element$listeners;
|
673
624
|
_handler = function handler() {
|
674
625
|
delete listeners[event][listener];
|
675
626
|
element.removeEventListener(event, _handler, options);
|
676
|
-
|
677
627
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
678
628
|
args[_key2] = arguments[_key2];
|
679
629
|
}
|
680
|
-
|
681
630
|
listener.apply(element, args);
|
682
631
|
};
|
683
|
-
|
684
632
|
if (!listeners[event]) {
|
685
633
|
listeners[event] = {};
|
686
634
|
}
|
687
|
-
|
688
635
|
if (listeners[event][listener]) {
|
689
636
|
element.removeEventListener(event, listeners[event][listener], options);
|
690
637
|
}
|
691
|
-
|
692
638
|
listeners[event][listener] = _handler;
|
693
639
|
element.listeners = listeners;
|
694
640
|
}
|
695
|
-
|
696
641
|
element.addEventListener(event, _handler, options);
|
697
642
|
});
|
698
643
|
}
|
644
|
+
|
699
645
|
/**
|
700
646
|
* Dispatch event on the target element.
|
701
647
|
* @param {Element} element - The event target.
|
@@ -703,10 +649,10 @@
|
|
703
649
|
* @param {Object} data - The additional event data.
|
704
650
|
* @returns {boolean} Indicate if the event is default prevented or not.
|
705
651
|
*/
|
706
|
-
|
707
652
|
function dispatchEvent(element, type, data) {
|
708
|
-
var event;
|
653
|
+
var event;
|
709
654
|
|
655
|
+
// Event and CustomEvent on IE9-11 are global objects, not constructors
|
710
656
|
if (isFunction(Event) && isFunction(CustomEvent)) {
|
711
657
|
event = new CustomEvent(type, {
|
712
658
|
detail: data,
|
@@ -717,15 +663,14 @@
|
|
717
663
|
event = document.createEvent('CustomEvent');
|
718
664
|
event.initCustomEvent(type, true, true, data);
|
719
665
|
}
|
720
|
-
|
721
666
|
return element.dispatchEvent(event);
|
722
667
|
}
|
668
|
+
|
723
669
|
/**
|
724
670
|
* Get the offset base on the document.
|
725
671
|
* @param {Element} element - The target element.
|
726
672
|
* @returns {Object} The offset data.
|
727
673
|
*/
|
728
|
-
|
729
674
|
function getOffset(element) {
|
730
675
|
var box = element.getBoundingClientRect();
|
731
676
|
return {
|
@@ -735,61 +680,56 @@
|
|
735
680
|
}
|
736
681
|
var location = WINDOW.location;
|
737
682
|
var REGEXP_ORIGINS = /^(\w+:)\/\/([^:/?#]*):?(\d*)/i;
|
683
|
+
|
738
684
|
/**
|
739
685
|
* Check if the given URL is a cross origin URL.
|
740
686
|
* @param {string} url - The target URL.
|
741
687
|
* @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`.
|
742
688
|
*/
|
743
|
-
|
744
689
|
function isCrossOriginURL(url) {
|
745
690
|
var parts = url.match(REGEXP_ORIGINS);
|
746
691
|
return parts !== null && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port);
|
747
692
|
}
|
693
|
+
|
748
694
|
/**
|
749
695
|
* Add timestamp to the given URL.
|
750
696
|
* @param {string} url - The target URL.
|
751
697
|
* @returns {string} The result URL.
|
752
698
|
*/
|
753
|
-
|
754
699
|
function addTimestamp(url) {
|
755
700
|
var timestamp = "timestamp=".concat(new Date().getTime());
|
756
701
|
return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp;
|
757
702
|
}
|
703
|
+
|
758
704
|
/**
|
759
705
|
* Get transforms base on the given object.
|
760
706
|
* @param {Object} obj - The target object.
|
761
707
|
* @returns {string} A string contains transform values.
|
762
708
|
*/
|
763
|
-
|
764
709
|
function getTransforms(_ref) {
|
765
710
|
var rotate = _ref.rotate,
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
711
|
+
scaleX = _ref.scaleX,
|
712
|
+
scaleY = _ref.scaleY,
|
713
|
+
translateX = _ref.translateX,
|
714
|
+
translateY = _ref.translateY;
|
770
715
|
var values = [];
|
771
|
-
|
772
716
|
if (isNumber(translateX) && translateX !== 0) {
|
773
717
|
values.push("translateX(".concat(translateX, "px)"));
|
774
718
|
}
|
775
|
-
|
776
719
|
if (isNumber(translateY) && translateY !== 0) {
|
777
720
|
values.push("translateY(".concat(translateY, "px)"));
|
778
|
-
}
|
779
|
-
|
721
|
+
}
|
780
722
|
|
723
|
+
// Rotate should come first before scale to match orientation transform
|
781
724
|
if (isNumber(rotate) && rotate !== 0) {
|
782
725
|
values.push("rotate(".concat(rotate, "deg)"));
|
783
726
|
}
|
784
|
-
|
785
727
|
if (isNumber(scaleX) && scaleX !== 1) {
|
786
728
|
values.push("scaleX(".concat(scaleX, ")"));
|
787
729
|
}
|
788
|
-
|
789
730
|
if (isNumber(scaleY) && scaleY !== 1) {
|
790
731
|
values.push("scaleY(".concat(scaleY, ")"));
|
791
732
|
}
|
792
|
-
|
793
733
|
var transform = values.length ? values.join(' ') : 'none';
|
794
734
|
return {
|
795
735
|
WebkitTransform: transform,
|
@@ -797,15 +737,14 @@
|
|
797
737
|
transform: transform
|
798
738
|
};
|
799
739
|
}
|
740
|
+
|
800
741
|
/**
|
801
742
|
* Get the max ratio of a group of pointers.
|
802
743
|
* @param {string} pointers - The target pointers.
|
803
744
|
* @returns {number} The result ratio.
|
804
745
|
*/
|
805
|
-
|
806
746
|
function getMaxZoomRatio(pointers) {
|
807
747
|
var pointers2 = _objectSpread2({}, pointers);
|
808
|
-
|
809
748
|
var maxRatio = 0;
|
810
749
|
forEach(pointers, function (pointer, pointerId) {
|
811
750
|
delete pointers2[pointerId];
|
@@ -817,7 +756,6 @@
|
|
817
756
|
var z1 = Math.sqrt(x1 * x1 + y1 * y1);
|
818
757
|
var z2 = Math.sqrt(x2 * x2 + y2 * y2);
|
819
758
|
var ratio = (z2 - z1) / z1;
|
820
|
-
|
821
759
|
if (Math.abs(ratio) > Math.abs(maxRatio)) {
|
822
760
|
maxRatio = ratio;
|
823
761
|
}
|
@@ -825,16 +763,16 @@
|
|
825
763
|
});
|
826
764
|
return maxRatio;
|
827
765
|
}
|
766
|
+
|
828
767
|
/**
|
829
768
|
* Get a pointer from an event object.
|
830
769
|
* @param {Object} event - The target event object.
|
831
770
|
* @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
|
832
771
|
* @returns {Object} The result pointer contains start and/or end point coordinates.
|
833
772
|
*/
|
834
|
-
|
835
773
|
function getPointer(_ref2, endOnly) {
|
836
774
|
var pageX = _ref2.pageX,
|
837
|
-
|
775
|
+
pageY = _ref2.pageY;
|
838
776
|
var end = {
|
839
777
|
endX: pageX,
|
840
778
|
endY: pageY
|
@@ -844,19 +782,19 @@
|
|
844
782
|
startY: pageY
|
845
783
|
}, end);
|
846
784
|
}
|
785
|
+
|
847
786
|
/**
|
848
787
|
* Get the center point coordinate of a group of pointers.
|
849
788
|
* @param {Object} pointers - The target pointers.
|
850
789
|
* @returns {Object} The center point coordinate.
|
851
790
|
*/
|
852
|
-
|
853
791
|
function getPointersCenter(pointers) {
|
854
792
|
var pageX = 0;
|
855
793
|
var pageY = 0;
|
856
794
|
var count = 0;
|
857
795
|
forEach(pointers, function (_ref3) {
|
858
796
|
var startX = _ref3.startX,
|
859
|
-
|
797
|
+
startY = _ref3.startY;
|
860
798
|
pageX += startX;
|
861
799
|
pageY += startY;
|
862
800
|
count += 1;
|
@@ -868,25 +806,22 @@
|
|
868
806
|
pageY: pageY
|
869
807
|
};
|
870
808
|
}
|
809
|
+
|
871
810
|
/**
|
872
811
|
* Get the max sizes in a rectangle under the given aspect ratio.
|
873
812
|
* @param {Object} data - The original sizes.
|
874
813
|
* @param {string} [type='contain'] - The adjust type.
|
875
814
|
* @returns {Object} The result sizes.
|
876
815
|
*/
|
877
|
-
|
878
|
-
function getAdjustedSizes(_ref4) // or 'cover'
|
879
|
-
{
|
816
|
+
function getAdjustedSizes(_ref4) {
|
880
817
|
var aspectRatio = _ref4.aspectRatio,
|
881
|
-
|
882
|
-
|
818
|
+
height = _ref4.height,
|
819
|
+
width = _ref4.width;
|
883
820
|
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'contain';
|
884
821
|
var isValidWidth = isPositiveNumber(width);
|
885
822
|
var isValidHeight = isPositiveNumber(height);
|
886
|
-
|
887
823
|
if (isValidWidth && isValidHeight) {
|
888
824
|
var adjustedWidth = height * aspectRatio;
|
889
|
-
|
890
825
|
if (type === 'contain' && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {
|
891
826
|
height = width / aspectRatio;
|
892
827
|
} else {
|
@@ -897,31 +832,28 @@
|
|
897
832
|
} else if (isValidHeight) {
|
898
833
|
width = height * aspectRatio;
|
899
834
|
}
|
900
|
-
|
901
835
|
return {
|
902
836
|
width: width,
|
903
837
|
height: height
|
904
838
|
};
|
905
839
|
}
|
840
|
+
|
906
841
|
/**
|
907
842
|
* Get the new sizes of a rectangle after rotated.
|
908
843
|
* @param {Object} data - The original sizes.
|
909
844
|
* @returns {Object} The result sizes.
|
910
845
|
*/
|
911
|
-
|
912
846
|
function getRotatedSizes(_ref5) {
|
913
847
|
var width = _ref5.width,
|
914
|
-
|
915
|
-
|
848
|
+
height = _ref5.height,
|
849
|
+
degree = _ref5.degree;
|
916
850
|
degree = Math.abs(degree) % 180;
|
917
|
-
|
918
851
|
if (degree === 90) {
|
919
852
|
return {
|
920
853
|
width: height,
|
921
854
|
height: width
|
922
855
|
};
|
923
856
|
}
|
924
|
-
|
925
857
|
var arc = degree % 90 * Math.PI / 180;
|
926
858
|
var sinArc = Math.sin(arc);
|
927
859
|
var cosArc = Math.cos(arc);
|
@@ -935,6 +867,7 @@
|
|
935
867
|
height: newHeight
|
936
868
|
};
|
937
869
|
}
|
870
|
+
|
938
871
|
/**
|
939
872
|
* Get a canvas which drew the given image.
|
940
873
|
* @param {HTMLImageElement} image - The image for drawing.
|
@@ -943,34 +876,33 @@
|
|
943
876
|
* @param {Object} options - The options.
|
944
877
|
* @returns {HTMLCanvasElement} The result canvas.
|
945
878
|
*/
|
946
|
-
|
947
879
|
function getSourceCanvas(image, _ref6, _ref7, _ref8) {
|
948
880
|
var imageAspectRatio = _ref6.aspectRatio,
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
881
|
+
imageNaturalWidth = _ref6.naturalWidth,
|
882
|
+
imageNaturalHeight = _ref6.naturalHeight,
|
883
|
+
_ref6$rotate = _ref6.rotate,
|
884
|
+
rotate = _ref6$rotate === void 0 ? 0 : _ref6$rotate,
|
885
|
+
_ref6$scaleX = _ref6.scaleX,
|
886
|
+
scaleX = _ref6$scaleX === void 0 ? 1 : _ref6$scaleX,
|
887
|
+
_ref6$scaleY = _ref6.scaleY,
|
888
|
+
scaleY = _ref6$scaleY === void 0 ? 1 : _ref6$scaleY;
|
957
889
|
var aspectRatio = _ref7.aspectRatio,
|
958
|
-
|
959
|
-
|
890
|
+
naturalWidth = _ref7.naturalWidth,
|
891
|
+
naturalHeight = _ref7.naturalHeight;
|
960
892
|
var _ref8$fillColor = _ref8.fillColor,
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
893
|
+
fillColor = _ref8$fillColor === void 0 ? 'transparent' : _ref8$fillColor,
|
894
|
+
_ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,
|
895
|
+
imageSmoothingEnabled = _ref8$imageSmoothingE === void 0 ? true : _ref8$imageSmoothingE,
|
896
|
+
_ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,
|
897
|
+
imageSmoothingQuality = _ref8$imageSmoothingQ === void 0 ? 'low' : _ref8$imageSmoothingQ,
|
898
|
+
_ref8$maxWidth = _ref8.maxWidth,
|
899
|
+
maxWidth = _ref8$maxWidth === void 0 ? Infinity : _ref8$maxWidth,
|
900
|
+
_ref8$maxHeight = _ref8.maxHeight,
|
901
|
+
maxHeight = _ref8$maxHeight === void 0 ? Infinity : _ref8$maxHeight,
|
902
|
+
_ref8$minWidth = _ref8.minWidth,
|
903
|
+
minWidth = _ref8$minWidth === void 0 ? 0 : _ref8$minWidth,
|
904
|
+
_ref8$minHeight = _ref8.minHeight,
|
905
|
+
minHeight = _ref8$minHeight === void 0 ? 0 : _ref8$minHeight;
|
974
906
|
var canvas = document.createElement('canvas');
|
975
907
|
var context = canvas.getContext('2d');
|
976
908
|
var maxSizes = getAdjustedSizes({
|
@@ -984,9 +916,10 @@
|
|
984
916
|
height: minHeight
|
985
917
|
}, 'cover');
|
986
918
|
var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth));
|
987
|
-
var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight));
|
988
|
-
// imageData.naturalWidth === canvasData.naturalHeight when rotate % 180 === 90
|
919
|
+
var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight));
|
989
920
|
|
921
|
+
// Note: should always use image's natural sizes for drawing as
|
922
|
+
// imageData.naturalWidth === canvasData.naturalHeight when rotate % 180 === 90
|
990
923
|
var destMaxSizes = getAdjustedSizes({
|
991
924
|
aspectRatio: imageAspectRatio,
|
992
925
|
width: maxWidth,
|
@@ -1017,6 +950,7 @@
|
|
1017
950
|
return canvas;
|
1018
951
|
}
|
1019
952
|
var fromCharCode = String.fromCharCode;
|
953
|
+
|
1020
954
|
/**
|
1021
955
|
* Get string from char code in data view.
|
1022
956
|
* @param {DataView} dataView - The data view for read.
|
@@ -1024,24 +958,21 @@
|
|
1024
958
|
* @param {number} length - The read length.
|
1025
959
|
* @returns {string} The read result.
|
1026
960
|
*/
|
1027
|
-
|
1028
961
|
function getStringFromCharCode(dataView, start, length) {
|
1029
962
|
var str = '';
|
1030
963
|
length += start;
|
1031
|
-
|
1032
964
|
for (var i = start; i < length; i += 1) {
|
1033
965
|
str += fromCharCode(dataView.getUint8(i));
|
1034
966
|
}
|
1035
|
-
|
1036
967
|
return str;
|
1037
968
|
}
|
1038
969
|
var REGEXP_DATA_URL_HEAD = /^data:.*,/;
|
970
|
+
|
1039
971
|
/**
|
1040
972
|
* Transform Data URL to array buffer.
|
1041
973
|
* @param {string} dataURL - The Data URL to transform.
|
1042
974
|
* @returns {ArrayBuffer} The result array buffer.
|
1043
975
|
*/
|
1044
|
-
|
1045
976
|
function dataURLToArrayBuffer(dataURL) {
|
1046
977
|
var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');
|
1047
978
|
var binary = atob(base64);
|
@@ -1052,158 +983,143 @@
|
|
1052
983
|
});
|
1053
984
|
return arrayBuffer;
|
1054
985
|
}
|
986
|
+
|
1055
987
|
/**
|
1056
988
|
* Transform array buffer to Data URL.
|
1057
989
|
* @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
|
1058
990
|
* @param {string} mimeType - The mime type of the Data URL.
|
1059
991
|
* @returns {string} The result Data URL.
|
1060
992
|
*/
|
1061
|
-
|
1062
993
|
function arrayBufferToDataURL(arrayBuffer, mimeType) {
|
1063
|
-
var chunks = [];
|
994
|
+
var chunks = [];
|
1064
995
|
|
996
|
+
// Chunk Typed Array for better performance (#435)
|
1065
997
|
var chunkSize = 8192;
|
1066
998
|
var uint8 = new Uint8Array(arrayBuffer);
|
1067
|
-
|
1068
999
|
while (uint8.length > 0) {
|
1069
1000
|
// XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9
|
1070
1001
|
// eslint-disable-next-line prefer-spread
|
1071
1002
|
chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));
|
1072
1003
|
uint8 = uint8.subarray(chunkSize);
|
1073
1004
|
}
|
1074
|
-
|
1075
1005
|
return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));
|
1076
1006
|
}
|
1007
|
+
|
1077
1008
|
/**
|
1078
1009
|
* Get orientation value from given array buffer.
|
1079
1010
|
* @param {ArrayBuffer} arrayBuffer - The array buffer to read.
|
1080
1011
|
* @returns {number} The read orientation value.
|
1081
1012
|
*/
|
1082
|
-
|
1083
1013
|
function resetAndGetOrientation(arrayBuffer) {
|
1084
1014
|
var dataView = new DataView(arrayBuffer);
|
1085
|
-
var orientation;
|
1015
|
+
var orientation;
|
1086
1016
|
|
1017
|
+
// Ignores range error when the image does not have correct Exif information
|
1087
1018
|
try {
|
1088
1019
|
var littleEndian;
|
1089
1020
|
var app1Start;
|
1090
|
-
var ifdStart;
|
1021
|
+
var ifdStart;
|
1091
1022
|
|
1023
|
+
// Only handle JPEG image (start by 0xFFD8)
|
1092
1024
|
if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
|
1093
1025
|
var length = dataView.byteLength;
|
1094
1026
|
var offset = 2;
|
1095
|
-
|
1096
1027
|
while (offset + 1 < length) {
|
1097
1028
|
if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
|
1098
1029
|
app1Start = offset;
|
1099
1030
|
break;
|
1100
1031
|
}
|
1101
|
-
|
1102
1032
|
offset += 1;
|
1103
1033
|
}
|
1104
1034
|
}
|
1105
|
-
|
1106
1035
|
if (app1Start) {
|
1107
1036
|
var exifIDCode = app1Start + 4;
|
1108
1037
|
var tiffOffset = app1Start + 10;
|
1109
|
-
|
1110
1038
|
if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
|
1111
1039
|
var endianness = dataView.getUint16(tiffOffset);
|
1112
1040
|
littleEndian = endianness === 0x4949;
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
|
1119
|
-
|
1120
|
-
if (firstIFDOffset >= 0x00000008) {
|
1121
|
-
ifdStart = tiffOffset + firstIFDOffset;
|
1122
|
-
}
|
1041
|
+
if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
|
1042
|
+
if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
|
1043
|
+
var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
|
1044
|
+
if (firstIFDOffset >= 0x00000008) {
|
1045
|
+
ifdStart = tiffOffset + firstIFDOffset;
|
1123
1046
|
}
|
1124
1047
|
}
|
1048
|
+
}
|
1125
1049
|
}
|
1126
1050
|
}
|
1127
|
-
|
1128
1051
|
if (ifdStart) {
|
1129
1052
|
var _length = dataView.getUint16(ifdStart, littleEndian);
|
1130
|
-
|
1131
1053
|
var _offset;
|
1132
|
-
|
1133
1054
|
var i;
|
1134
|
-
|
1135
1055
|
for (i = 0; i < _length; i += 1) {
|
1136
1056
|
_offset = ifdStart + i * 12 + 2;
|
1057
|
+
if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) {
|
1058
|
+
// 8 is the offset of the current tag's value
|
1059
|
+
_offset += 8;
|
1137
1060
|
|
1138
|
-
|
1139
|
-
|
1140
|
-
) {
|
1141
|
-
// 8 is the offset of the current tag's value
|
1142
|
-
_offset += 8; // Get the original orientation value
|
1143
|
-
|
1144
|
-
orientation = dataView.getUint16(_offset, littleEndian); // Override the orientation with its default value
|
1061
|
+
// Get the original orientation value
|
1062
|
+
orientation = dataView.getUint16(_offset, littleEndian);
|
1145
1063
|
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1064
|
+
// Override the orientation with its default value
|
1065
|
+
dataView.setUint16(_offset, 1, littleEndian);
|
1066
|
+
break;
|
1067
|
+
}
|
1149
1068
|
}
|
1150
1069
|
}
|
1151
1070
|
} catch (error) {
|
1152
1071
|
orientation = 1;
|
1153
1072
|
}
|
1154
|
-
|
1155
1073
|
return orientation;
|
1156
1074
|
}
|
1075
|
+
|
1157
1076
|
/**
|
1158
1077
|
* Parse Exif Orientation value.
|
1159
1078
|
* @param {number} orientation - The orientation to parse.
|
1160
1079
|
* @returns {Object} The parsed result.
|
1161
1080
|
*/
|
1162
|
-
|
1163
1081
|
function parseOrientation(orientation) {
|
1164
1082
|
var rotate = 0;
|
1165
1083
|
var scaleX = 1;
|
1166
1084
|
var scaleY = 1;
|
1167
|
-
|
1168
1085
|
switch (orientation) {
|
1169
1086
|
// Flip horizontal
|
1170
1087
|
case 2:
|
1171
1088
|
scaleX = -1;
|
1172
1089
|
break;
|
1173
|
-
// Rotate left 180°
|
1174
1090
|
|
1091
|
+
// Rotate left 180°
|
1175
1092
|
case 3:
|
1176
1093
|
rotate = -180;
|
1177
1094
|
break;
|
1178
|
-
// Flip vertical
|
1179
1095
|
|
1096
|
+
// Flip vertical
|
1180
1097
|
case 4:
|
1181
1098
|
scaleY = -1;
|
1182
1099
|
break;
|
1183
|
-
// Flip vertical and rotate right 90°
|
1184
1100
|
|
1101
|
+
// Flip vertical and rotate right 90°
|
1185
1102
|
case 5:
|
1186
1103
|
rotate = 90;
|
1187
1104
|
scaleY = -1;
|
1188
1105
|
break;
|
1189
|
-
// Rotate right 90°
|
1190
1106
|
|
1107
|
+
// Rotate right 90°
|
1191
1108
|
case 6:
|
1192
1109
|
rotate = 90;
|
1193
1110
|
break;
|
1194
|
-
// Flip horizontal and rotate right 90°
|
1195
1111
|
|
1112
|
+
// Flip horizontal and rotate right 90°
|
1196
1113
|
case 7:
|
1197
1114
|
rotate = 90;
|
1198
1115
|
scaleX = -1;
|
1199
1116
|
break;
|
1200
|
-
// Rotate left 90°
|
1201
1117
|
|
1118
|
+
// Rotate left 90°
|
1202
1119
|
case 8:
|
1203
1120
|
rotate = -90;
|
1204
1121
|
break;
|
1205
1122
|
}
|
1206
|
-
|
1207
1123
|
return {
|
1208
1124
|
rotate: rotate,
|
1209
1125
|
scaleX: scaleX,
|
@@ -1217,16 +1133,15 @@
|
|
1217
1133
|
this.initCanvas();
|
1218
1134
|
this.initCropBox();
|
1219
1135
|
this.renderCanvas();
|
1220
|
-
|
1221
1136
|
if (this.cropped) {
|
1222
1137
|
this.renderCropBox();
|
1223
1138
|
}
|
1224
1139
|
},
|
1225
1140
|
initContainer: function initContainer() {
|
1226
1141
|
var element = this.element,
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1142
|
+
options = this.options,
|
1143
|
+
container = this.container,
|
1144
|
+
cropper = this.cropper;
|
1230
1145
|
var minWidth = Number(options.minContainerWidth);
|
1231
1146
|
var minHeight = Number(options.minContainerHeight);
|
1232
1147
|
addClass(cropper, CLASS_HIDDEN);
|
@@ -1246,7 +1161,7 @@
|
|
1246
1161
|
// Canvas (image wrapper)
|
1247
1162
|
initCanvas: function initCanvas() {
|
1248
1163
|
var containerData = this.containerData,
|
1249
|
-
|
1164
|
+
imageData = this.imageData;
|
1250
1165
|
var viewMode = this.options.viewMode;
|
1251
1166
|
var rotated = Math.abs(imageData.rotate) % 180 === 90;
|
1252
1167
|
var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;
|
@@ -1254,7 +1169,6 @@
|
|
1254
1169
|
var aspectRatio = naturalWidth / naturalHeight;
|
1255
1170
|
var canvasWidth = containerData.width;
|
1256
1171
|
var canvasHeight = containerData.height;
|
1257
|
-
|
1258
1172
|
if (containerData.height * aspectRatio > containerData.width) {
|
1259
1173
|
if (viewMode === 3) {
|
1260
1174
|
canvasWidth = containerData.height * aspectRatio;
|
@@ -1266,7 +1180,6 @@
|
|
1266
1180
|
} else {
|
1267
1181
|
canvasWidth = containerData.height * aspectRatio;
|
1268
1182
|
}
|
1269
|
-
|
1270
1183
|
var canvasData = {
|
1271
1184
|
aspectRatio: aspectRatio,
|
1272
1185
|
naturalWidth: naturalWidth,
|
@@ -1287,21 +1200,18 @@
|
|
1287
1200
|
},
|
1288
1201
|
limitCanvas: function limitCanvas(sizeLimited, positionLimited) {
|
1289
1202
|
var options = this.options,
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1203
|
+
containerData = this.containerData,
|
1204
|
+
canvasData = this.canvasData,
|
1205
|
+
cropBoxData = this.cropBoxData;
|
1293
1206
|
var viewMode = options.viewMode;
|
1294
1207
|
var aspectRatio = canvasData.aspectRatio;
|
1295
1208
|
var cropped = this.cropped && cropBoxData;
|
1296
|
-
|
1297
1209
|
if (sizeLimited) {
|
1298
1210
|
var minCanvasWidth = Number(options.minCanvasWidth) || 0;
|
1299
1211
|
var minCanvasHeight = Number(options.minCanvasHeight) || 0;
|
1300
|
-
|
1301
1212
|
if (viewMode > 1) {
|
1302
1213
|
minCanvasWidth = Math.max(minCanvasWidth, containerData.width);
|
1303
1214
|
minCanvasHeight = Math.max(minCanvasHeight, containerData.height);
|
1304
|
-
|
1305
1215
|
if (viewMode === 3) {
|
1306
1216
|
if (minCanvasHeight * aspectRatio > minCanvasWidth) {
|
1307
1217
|
minCanvasWidth = minCanvasHeight * aspectRatio;
|
@@ -1317,7 +1227,6 @@
|
|
1317
1227
|
} else if (cropped) {
|
1318
1228
|
minCanvasWidth = cropBoxData.width;
|
1319
1229
|
minCanvasHeight = cropBoxData.height;
|
1320
|
-
|
1321
1230
|
if (minCanvasHeight * aspectRatio > minCanvasWidth) {
|
1322
1231
|
minCanvasWidth = minCanvasHeight * aspectRatio;
|
1323
1232
|
} else {
|
@@ -1325,13 +1234,11 @@
|
|
1325
1234
|
}
|
1326
1235
|
}
|
1327
1236
|
}
|
1328
|
-
|
1329
1237
|
var _getAdjustedSizes = getAdjustedSizes({
|
1330
1238
|
aspectRatio: aspectRatio,
|
1331
1239
|
width: minCanvasWidth,
|
1332
1240
|
height: minCanvasHeight
|
1333
1241
|
});
|
1334
|
-
|
1335
1242
|
minCanvasWidth = _getAdjustedSizes.width;
|
1336
1243
|
minCanvasHeight = _getAdjustedSizes.height;
|
1337
1244
|
canvasData.minWidth = minCanvasWidth;
|
@@ -1339,7 +1246,6 @@
|
|
1339
1246
|
canvasData.maxWidth = Infinity;
|
1340
1247
|
canvasData.maxHeight = Infinity;
|
1341
1248
|
}
|
1342
|
-
|
1343
1249
|
if (positionLimited) {
|
1344
1250
|
if (viewMode > (cropped ? 0 : 1)) {
|
1345
1251
|
var newCanvasLeft = containerData.width - canvasData.width;
|
@@ -1348,19 +1254,16 @@
|
|
1348
1254
|
canvasData.minTop = Math.min(0, newCanvasTop);
|
1349
1255
|
canvasData.maxLeft = Math.max(0, newCanvasLeft);
|
1350
1256
|
canvasData.maxTop = Math.max(0, newCanvasTop);
|
1351
|
-
|
1352
1257
|
if (cropped && this.limited) {
|
1353
1258
|
canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width));
|
1354
1259
|
canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height));
|
1355
1260
|
canvasData.maxLeft = cropBoxData.left;
|
1356
1261
|
canvasData.maxTop = cropBoxData.top;
|
1357
|
-
|
1358
1262
|
if (viewMode === 2) {
|
1359
1263
|
if (canvasData.width >= containerData.width) {
|
1360
1264
|
canvasData.minLeft = Math.min(0, newCanvasLeft);
|
1361
1265
|
canvasData.maxLeft = Math.max(0, newCanvasLeft);
|
1362
1266
|
}
|
1363
|
-
|
1364
1267
|
if (canvasData.height >= containerData.height) {
|
1365
1268
|
canvasData.minTop = Math.min(0, newCanvasTop);
|
1366
1269
|
canvasData.maxTop = Math.max(0, newCanvasTop);
|
@@ -1377,17 +1280,15 @@
|
|
1377
1280
|
},
|
1378
1281
|
renderCanvas: function renderCanvas(changed, transformed) {
|
1379
1282
|
var canvasData = this.canvasData,
|
1380
|
-
|
1381
|
-
|
1283
|
+
imageData = this.imageData;
|
1382
1284
|
if (transformed) {
|
1383
1285
|
var _getRotatedSizes = getRotatedSizes({
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1286
|
+
width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),
|
1287
|
+
height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),
|
1288
|
+
degree: imageData.rotate || 0
|
1289
|
+
}),
|
1290
|
+
naturalWidth = _getRotatedSizes.width,
|
1291
|
+
naturalHeight = _getRotatedSizes.height;
|
1391
1292
|
var width = canvasData.width * (naturalWidth / canvasData.naturalWidth);
|
1392
1293
|
var height = canvasData.height * (naturalHeight / canvasData.naturalHeight);
|
1393
1294
|
canvasData.left -= (width - canvasData.width) / 2;
|
@@ -1399,15 +1300,12 @@
|
|
1399
1300
|
canvasData.naturalHeight = naturalHeight;
|
1400
1301
|
this.limitCanvas(true, false);
|
1401
1302
|
}
|
1402
|
-
|
1403
1303
|
if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) {
|
1404
1304
|
canvasData.left = canvasData.oldLeft;
|
1405
1305
|
}
|
1406
|
-
|
1407
1306
|
if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) {
|
1408
1307
|
canvasData.top = canvasData.oldTop;
|
1409
1308
|
}
|
1410
|
-
|
1411
1309
|
canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);
|
1412
1310
|
canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);
|
1413
1311
|
this.limitCanvas(false, true);
|
@@ -1423,14 +1321,13 @@
|
|
1423
1321
|
translateY: canvasData.top
|
1424
1322
|
})));
|
1425
1323
|
this.renderImage(changed);
|
1426
|
-
|
1427
1324
|
if (this.cropped && this.limited) {
|
1428
1325
|
this.limitCropBox(true, true);
|
1429
1326
|
}
|
1430
1327
|
},
|
1431
1328
|
renderImage: function renderImage(changed) {
|
1432
1329
|
var canvasData = this.canvasData,
|
1433
|
-
|
1330
|
+
imageData = this.imageData;
|
1434
1331
|
var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);
|
1435
1332
|
var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);
|
1436
1333
|
assign(imageData, {
|
@@ -1446,21 +1343,19 @@
|
|
1446
1343
|
translateX: imageData.left,
|
1447
1344
|
translateY: imageData.top
|
1448
1345
|
}, imageData))));
|
1449
|
-
|
1450
1346
|
if (changed) {
|
1451
1347
|
this.output();
|
1452
1348
|
}
|
1453
1349
|
},
|
1454
1350
|
initCropBox: function initCropBox() {
|
1455
1351
|
var options = this.options,
|
1456
|
-
|
1352
|
+
canvasData = this.canvasData;
|
1457
1353
|
var aspectRatio = options.aspectRatio || options.initialAspectRatio;
|
1458
1354
|
var autoCropArea = Number(options.autoCropArea) || 0.8;
|
1459
1355
|
var cropBoxData = {
|
1460
1356
|
width: canvasData.width,
|
1461
1357
|
height: canvasData.height
|
1462
1358
|
};
|
1463
|
-
|
1464
1359
|
if (aspectRatio) {
|
1465
1360
|
if (canvasData.height * aspectRatio > canvasData.width) {
|
1466
1361
|
cropBoxData.height = cropBoxData.width / aspectRatio;
|
@@ -1468,13 +1363,14 @@
|
|
1468
1363
|
cropBoxData.width = cropBoxData.height * aspectRatio;
|
1469
1364
|
}
|
1470
1365
|
}
|
1471
|
-
|
1472
1366
|
this.cropBoxData = cropBoxData;
|
1473
|
-
this.limitCropBox(true, true);
|
1367
|
+
this.limitCropBox(true, true);
|
1474
1368
|
|
1369
|
+
// Initialize auto crop area
|
1475
1370
|
cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
|
1476
|
-
cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
|
1371
|
+
cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
|
1477
1372
|
|
1373
|
+
// The width/height of auto crop area must large than "minWidth/Height"
|
1478
1374
|
cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea);
|
1479
1375
|
cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea);
|
1480
1376
|
cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2;
|
@@ -1485,21 +1381,20 @@
|
|
1485
1381
|
},
|
1486
1382
|
limitCropBox: function limitCropBox(sizeLimited, positionLimited) {
|
1487
1383
|
var options = this.options,
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1384
|
+
containerData = this.containerData,
|
1385
|
+
canvasData = this.canvasData,
|
1386
|
+
cropBoxData = this.cropBoxData,
|
1387
|
+
limited = this.limited;
|
1492
1388
|
var aspectRatio = options.aspectRatio;
|
1493
|
-
|
1494
1389
|
if (sizeLimited) {
|
1495
1390
|
var minCropBoxWidth = Number(options.minCropBoxWidth) || 0;
|
1496
1391
|
var minCropBoxHeight = Number(options.minCropBoxHeight) || 0;
|
1497
1392
|
var maxCropBoxWidth = limited ? Math.min(containerData.width, canvasData.width, canvasData.width + canvasData.left, containerData.width - canvasData.left) : containerData.width;
|
1498
|
-
var maxCropBoxHeight = limited ? Math.min(containerData.height, canvasData.height, canvasData.height + canvasData.top, containerData.height - canvasData.top) : containerData.height;
|
1393
|
+
var maxCropBoxHeight = limited ? Math.min(containerData.height, canvasData.height, canvasData.height + canvasData.top, containerData.height - canvasData.top) : containerData.height;
|
1499
1394
|
|
1395
|
+
// The min/maxCropBoxWidth/Height must be less than container's width/height
|
1500
1396
|
minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);
|
1501
1397
|
minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);
|
1502
|
-
|
1503
1398
|
if (aspectRatio) {
|
1504
1399
|
if (minCropBoxWidth && minCropBoxHeight) {
|
1505
1400
|
if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {
|
@@ -1512,21 +1407,19 @@
|
|
1512
1407
|
} else if (minCropBoxHeight) {
|
1513
1408
|
minCropBoxWidth = minCropBoxHeight * aspectRatio;
|
1514
1409
|
}
|
1515
|
-
|
1516
1410
|
if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {
|
1517
1411
|
maxCropBoxHeight = maxCropBoxWidth / aspectRatio;
|
1518
1412
|
} else {
|
1519
1413
|
maxCropBoxWidth = maxCropBoxHeight * aspectRatio;
|
1520
1414
|
}
|
1521
|
-
}
|
1522
|
-
|
1415
|
+
}
|
1523
1416
|
|
1417
|
+
// The minWidth/Height must be less than maxWidth/Height
|
1524
1418
|
cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);
|
1525
1419
|
cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);
|
1526
1420
|
cropBoxData.maxWidth = maxCropBoxWidth;
|
1527
1421
|
cropBoxData.maxHeight = maxCropBoxHeight;
|
1528
1422
|
}
|
1529
|
-
|
1530
1423
|
if (positionLimited) {
|
1531
1424
|
if (limited) {
|
1532
1425
|
cropBoxData.minLeft = Math.max(0, canvasData.left);
|
@@ -1543,17 +1436,14 @@
|
|
1543
1436
|
},
|
1544
1437
|
renderCropBox: function renderCropBox() {
|
1545
1438
|
var options = this.options,
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1439
|
+
containerData = this.containerData,
|
1440
|
+
cropBoxData = this.cropBoxData;
|
1549
1441
|
if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) {
|
1550
1442
|
cropBoxData.left = cropBoxData.oldLeft;
|
1551
1443
|
}
|
1552
|
-
|
1553
1444
|
if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) {
|
1554
1445
|
cropBoxData.top = cropBoxData.oldTop;
|
1555
1446
|
}
|
1556
|
-
|
1557
1447
|
cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
|
1558
1448
|
cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
|
1559
1449
|
this.limitCropBox(false, true);
|
@@ -1561,12 +1451,10 @@
|
|
1561
1451
|
cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop);
|
1562
1452
|
cropBoxData.oldLeft = cropBoxData.left;
|
1563
1453
|
cropBoxData.oldTop = cropBoxData.top;
|
1564
|
-
|
1565
1454
|
if (options.movable && options.cropBoxMovable) {
|
1566
1455
|
// Turn to move the canvas when the crop box is equal to the container
|
1567
1456
|
setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);
|
1568
1457
|
}
|
1569
|
-
|
1570
1458
|
setStyle(this.cropBox, assign({
|
1571
1459
|
width: cropBoxData.width,
|
1572
1460
|
height: cropBoxData.height
|
@@ -1574,11 +1462,9 @@
|
|
1574
1462
|
translateX: cropBoxData.left,
|
1575
1463
|
translateY: cropBoxData.top
|
1576
1464
|
})));
|
1577
|
-
|
1578
1465
|
if (this.cropped && this.limited) {
|
1579
1466
|
this.limitCanvas(true, true);
|
1580
1467
|
}
|
1581
|
-
|
1582
1468
|
if (!this.disabled) {
|
1583
1469
|
this.output();
|
1584
1470
|
}
|
@@ -1592,56 +1478,49 @@
|
|
1592
1478
|
var preview = {
|
1593
1479
|
initPreview: function initPreview() {
|
1594
1480
|
var element = this.element,
|
1595
|
-
|
1481
|
+
crossOrigin = this.crossOrigin;
|
1596
1482
|
var preview = this.options.preview;
|
1597
1483
|
var url = crossOrigin ? this.crossOriginUrl : this.url;
|
1598
1484
|
var alt = element.alt || 'The image to preview';
|
1599
1485
|
var image = document.createElement('img');
|
1600
|
-
|
1601
1486
|
if (crossOrigin) {
|
1602
1487
|
image.crossOrigin = crossOrigin;
|
1603
1488
|
}
|
1604
|
-
|
1605
1489
|
image.src = url;
|
1606
1490
|
image.alt = alt;
|
1607
1491
|
this.viewBox.appendChild(image);
|
1608
1492
|
this.viewBoxImage = image;
|
1609
|
-
|
1610
1493
|
if (!preview) {
|
1611
1494
|
return;
|
1612
1495
|
}
|
1613
|
-
|
1614
1496
|
var previews = preview;
|
1615
|
-
|
1616
1497
|
if (typeof preview === 'string') {
|
1617
1498
|
previews = element.ownerDocument.querySelectorAll(preview);
|
1618
1499
|
} else if (preview.querySelector) {
|
1619
1500
|
previews = [preview];
|
1620
1501
|
}
|
1621
|
-
|
1622
1502
|
this.previews = previews;
|
1623
1503
|
forEach(previews, function (el) {
|
1624
|
-
var img = document.createElement('img');
|
1504
|
+
var img = document.createElement('img');
|
1625
1505
|
|
1506
|
+
// Save the original size for recover
|
1626
1507
|
setData(el, DATA_PREVIEW, {
|
1627
1508
|
width: el.offsetWidth,
|
1628
1509
|
height: el.offsetHeight,
|
1629
1510
|
html: el.innerHTML
|
1630
1511
|
});
|
1631
|
-
|
1632
1512
|
if (crossOrigin) {
|
1633
1513
|
img.crossOrigin = crossOrigin;
|
1634
1514
|
}
|
1635
|
-
|
1636
1515
|
img.src = url;
|
1637
1516
|
img.alt = alt;
|
1517
|
+
|
1638
1518
|
/**
|
1639
1519
|
* Override img element styles
|
1640
1520
|
* Add `display:block` to avoid margin top issue
|
1641
1521
|
* Add `height:auto` to override `height` attribute on IE8
|
1642
1522
|
* (Occur only when margin-top <= -height)
|
1643
1523
|
*/
|
1644
|
-
|
1645
1524
|
img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"';
|
1646
1525
|
el.innerHTML = '';
|
1647
1526
|
el.appendChild(img);
|
@@ -1660,19 +1539,17 @@
|
|
1660
1539
|
},
|
1661
1540
|
preview: function preview() {
|
1662
1541
|
var imageData = this.imageData,
|
1663
|
-
|
1664
|
-
|
1542
|
+
canvasData = this.canvasData,
|
1543
|
+
cropBoxData = this.cropBoxData;
|
1665
1544
|
var cropBoxWidth = cropBoxData.width,
|
1666
|
-
|
1545
|
+
cropBoxHeight = cropBoxData.height;
|
1667
1546
|
var width = imageData.width,
|
1668
|
-
|
1547
|
+
height = imageData.height;
|
1669
1548
|
var left = cropBoxData.left - canvasData.left - imageData.left;
|
1670
1549
|
var top = cropBoxData.top - canvasData.top - imageData.top;
|
1671
|
-
|
1672
1550
|
if (!this.cropped || this.disabled) {
|
1673
1551
|
return;
|
1674
1552
|
}
|
1675
|
-
|
1676
1553
|
setStyle(this.viewBoxImage, assign({
|
1677
1554
|
width: width,
|
1678
1555
|
height: height
|
@@ -1687,18 +1564,15 @@
|
|
1687
1564
|
var newWidth = originalWidth;
|
1688
1565
|
var newHeight = originalHeight;
|
1689
1566
|
var ratio = 1;
|
1690
|
-
|
1691
1567
|
if (cropBoxWidth) {
|
1692
1568
|
ratio = originalWidth / cropBoxWidth;
|
1693
1569
|
newHeight = cropBoxHeight * ratio;
|
1694
1570
|
}
|
1695
|
-
|
1696
1571
|
if (cropBoxHeight && newHeight > originalHeight) {
|
1697
1572
|
ratio = originalHeight / cropBoxHeight;
|
1698
1573
|
newWidth = cropBoxWidth * ratio;
|
1699
1574
|
newHeight = originalHeight;
|
1700
1575
|
}
|
1701
|
-
|
1702
1576
|
setStyle(element, {
|
1703
1577
|
width: newWidth,
|
1704
1578
|
height: newHeight
|
@@ -1717,90 +1591,70 @@
|
|
1717
1591
|
var events = {
|
1718
1592
|
bind: function bind() {
|
1719
1593
|
var element = this.element,
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1594
|
+
options = this.options,
|
1595
|
+
cropper = this.cropper;
|
1723
1596
|
if (isFunction(options.cropstart)) {
|
1724
1597
|
addListener(element, EVENT_CROP_START, options.cropstart);
|
1725
1598
|
}
|
1726
|
-
|
1727
1599
|
if (isFunction(options.cropmove)) {
|
1728
1600
|
addListener(element, EVENT_CROP_MOVE, options.cropmove);
|
1729
1601
|
}
|
1730
|
-
|
1731
1602
|
if (isFunction(options.cropend)) {
|
1732
1603
|
addListener(element, EVENT_CROP_END, options.cropend);
|
1733
1604
|
}
|
1734
|
-
|
1735
1605
|
if (isFunction(options.crop)) {
|
1736
1606
|
addListener(element, EVENT_CROP, options.crop);
|
1737
1607
|
}
|
1738
|
-
|
1739
1608
|
if (isFunction(options.zoom)) {
|
1740
1609
|
addListener(element, EVENT_ZOOM, options.zoom);
|
1741
1610
|
}
|
1742
|
-
|
1743
1611
|
addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this));
|
1744
|
-
|
1745
1612
|
if (options.zoomable && options.zoomOnWheel) {
|
1746
1613
|
addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {
|
1747
1614
|
passive: false,
|
1748
1615
|
capture: true
|
1749
1616
|
});
|
1750
1617
|
}
|
1751
|
-
|
1752
1618
|
if (options.toggleDragModeOnDblclick) {
|
1753
1619
|
addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
|
1754
1620
|
}
|
1755
|
-
|
1756
1621
|
addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this));
|
1757
1622
|
addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this));
|
1758
|
-
|
1759
1623
|
if (options.responsive) {
|
1760
1624
|
addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
|
1761
1625
|
}
|
1762
1626
|
},
|
1763
1627
|
unbind: function unbind() {
|
1764
1628
|
var element = this.element,
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1629
|
+
options = this.options,
|
1630
|
+
cropper = this.cropper;
|
1768
1631
|
if (isFunction(options.cropstart)) {
|
1769
1632
|
removeListener(element, EVENT_CROP_START, options.cropstart);
|
1770
1633
|
}
|
1771
|
-
|
1772
1634
|
if (isFunction(options.cropmove)) {
|
1773
1635
|
removeListener(element, EVENT_CROP_MOVE, options.cropmove);
|
1774
1636
|
}
|
1775
|
-
|
1776
1637
|
if (isFunction(options.cropend)) {
|
1777
1638
|
removeListener(element, EVENT_CROP_END, options.cropend);
|
1778
1639
|
}
|
1779
|
-
|
1780
1640
|
if (isFunction(options.crop)) {
|
1781
1641
|
removeListener(element, EVENT_CROP, options.crop);
|
1782
1642
|
}
|
1783
|
-
|
1784
1643
|
if (isFunction(options.zoom)) {
|
1785
1644
|
removeListener(element, EVENT_ZOOM, options.zoom);
|
1786
1645
|
}
|
1787
|
-
|
1788
1646
|
removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);
|
1789
|
-
|
1790
1647
|
if (options.zoomable && options.zoomOnWheel) {
|
1791
1648
|
removeListener(cropper, EVENT_WHEEL, this.onWheel, {
|
1792
1649
|
passive: false,
|
1793
1650
|
capture: true
|
1794
1651
|
});
|
1795
1652
|
}
|
1796
|
-
|
1797
1653
|
if (options.toggleDragModeOnDblclick) {
|
1798
1654
|
removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);
|
1799
1655
|
}
|
1800
|
-
|
1801
1656
|
removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);
|
1802
1657
|
removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);
|
1803
|
-
|
1804
1658
|
if (options.responsive) {
|
1805
1659
|
removeListener(window, EVENT_RESIZE, this.onResize);
|
1806
1660
|
}
|
@@ -1812,23 +1666,22 @@
|
|
1812
1666
|
if (this.disabled) {
|
1813
1667
|
return;
|
1814
1668
|
}
|
1815
|
-
|
1816
1669
|
var options = this.options,
|
1817
|
-
|
1818
|
-
|
1819
|
-
var
|
1670
|
+
container = this.container,
|
1671
|
+
containerData = this.containerData;
|
1672
|
+
var ratioX = container.offsetWidth / containerData.width;
|
1673
|
+
var ratioY = container.offsetHeight / containerData.height;
|
1674
|
+
var ratio = Math.abs(ratioX - 1) > Math.abs(ratioY - 1) ? ratioX : ratioY;
|
1820
1675
|
|
1821
|
-
|
1676
|
+
// Resize when width changed or height changed
|
1677
|
+
if (ratio !== 1) {
|
1822
1678
|
var canvasData;
|
1823
1679
|
var cropBoxData;
|
1824
|
-
|
1825
1680
|
if (options.restore) {
|
1826
1681
|
canvasData = this.getCanvasData();
|
1827
1682
|
cropBoxData = this.getCropBoxData();
|
1828
1683
|
}
|
1829
|
-
|
1830
1684
|
this.render();
|
1831
|
-
|
1832
1685
|
if (options.restore) {
|
1833
1686
|
this.setCanvasData(forEach(canvasData, function (n, i) {
|
1834
1687
|
canvasData[i] = n * ratio;
|
@@ -1843,30 +1696,25 @@
|
|
1843
1696
|
if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {
|
1844
1697
|
return;
|
1845
1698
|
}
|
1846
|
-
|
1847
1699
|
this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);
|
1848
1700
|
},
|
1849
1701
|
wheel: function wheel(event) {
|
1850
1702
|
var _this = this;
|
1851
|
-
|
1852
1703
|
var ratio = Number(this.options.wheelZoomRatio) || 0.1;
|
1853
1704
|
var delta = 1;
|
1854
|
-
|
1855
1705
|
if (this.disabled) {
|
1856
1706
|
return;
|
1857
1707
|
}
|
1708
|
+
event.preventDefault();
|
1858
1709
|
|
1859
|
-
|
1860
|
-
|
1710
|
+
// Limit wheel speed to prevent zoom too fast (#21)
|
1861
1711
|
if (this.wheeling) {
|
1862
1712
|
return;
|
1863
1713
|
}
|
1864
|
-
|
1865
1714
|
this.wheeling = true;
|
1866
1715
|
setTimeout(function () {
|
1867
1716
|
_this.wheeling = false;
|
1868
1717
|
}, 50);
|
1869
|
-
|
1870
1718
|
if (event.deltaY) {
|
1871
1719
|
delta = event.deltaY > 0 ? 1 : -1;
|
1872
1720
|
} else if (event.wheelDelta) {
|
@@ -1874,24 +1722,25 @@
|
|
1874
1722
|
} else if (event.detail) {
|
1875
1723
|
delta = event.detail > 0 ? 1 : -1;
|
1876
1724
|
}
|
1877
|
-
|
1878
1725
|
this.zoom(-delta * ratio, event);
|
1879
1726
|
},
|
1880
1727
|
cropStart: function cropStart(event) {
|
1881
1728
|
var buttons = event.buttons,
|
1882
|
-
|
1729
|
+
button = event.button;
|
1730
|
+
if (this.disabled
|
1731
|
+
|
1732
|
+
// Handle mouse event and pointer event and ignore touch event
|
1733
|
+
|| (event.type === 'mousedown' || event.type === 'pointerdown' && event.pointerType === 'mouse') && (
|
1734
|
+
// No primary button (Usually the left button)
|
1735
|
+
isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0
|
1883
1736
|
|
1884
|
-
|
1885
|
-
|| (event.type === 'mousedown' || event.type === 'pointerdown' && event.pointerType === 'mouse') && ( // No primary button (Usually the left button)
|
1886
|
-
isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0 // Open context menu
|
1737
|
+
// Open context menu
|
1887
1738
|
|| event.ctrlKey)) {
|
1888
1739
|
return;
|
1889
1740
|
}
|
1890
|
-
|
1891
1741
|
var options = this.options,
|
1892
|
-
|
1742
|
+
pointers = this.pointers;
|
1893
1743
|
var action;
|
1894
|
-
|
1895
1744
|
if (event.changedTouches) {
|
1896
1745
|
// Handle touch event
|
1897
1746
|
forEach(event.changedTouches, function (touch) {
|
@@ -1901,29 +1750,25 @@
|
|
1901
1750
|
// Handle mouse event and pointer event
|
1902
1751
|
pointers[event.pointerId || 0] = getPointer(event);
|
1903
1752
|
}
|
1904
|
-
|
1905
1753
|
if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {
|
1906
1754
|
action = ACTION_ZOOM;
|
1907
1755
|
} else {
|
1908
1756
|
action = getData(event.target, DATA_ACTION);
|
1909
1757
|
}
|
1910
|
-
|
1911
1758
|
if (!REGEXP_ACTIONS.test(action)) {
|
1912
1759
|
return;
|
1913
1760
|
}
|
1914
|
-
|
1915
1761
|
if (dispatchEvent(this.element, EVENT_CROP_START, {
|
1916
1762
|
originalEvent: event,
|
1917
1763
|
action: action
|
1918
1764
|
}) === false) {
|
1919
1765
|
return;
|
1920
|
-
}
|
1921
|
-
|
1766
|
+
}
|
1922
1767
|
|
1768
|
+
// This line is required for preventing page zooming in iOS browsers
|
1923
1769
|
event.preventDefault();
|
1924
1770
|
this.action = action;
|
1925
1771
|
this.cropping = false;
|
1926
|
-
|
1927
1772
|
if (action === ACTION_CROP) {
|
1928
1773
|
this.cropping = true;
|
1929
1774
|
addClass(this.dragBox, CLASS_MODAL);
|
@@ -1931,21 +1776,17 @@
|
|
1931
1776
|
},
|
1932
1777
|
cropMove: function cropMove(event) {
|
1933
1778
|
var action = this.action;
|
1934
|
-
|
1935
1779
|
if (this.disabled || !action) {
|
1936
1780
|
return;
|
1937
1781
|
}
|
1938
|
-
|
1939
1782
|
var pointers = this.pointers;
|
1940
1783
|
event.preventDefault();
|
1941
|
-
|
1942
1784
|
if (dispatchEvent(this.element, EVENT_CROP_MOVE, {
|
1943
1785
|
originalEvent: event,
|
1944
1786
|
action: action
|
1945
1787
|
}) === false) {
|
1946
1788
|
return;
|
1947
1789
|
}
|
1948
|
-
|
1949
1790
|
if (event.changedTouches) {
|
1950
1791
|
forEach(event.changedTouches, function (touch) {
|
1951
1792
|
// The first parameter should not be undefined (#432)
|
@@ -1954,17 +1795,14 @@
|
|
1954
1795
|
} else {
|
1955
1796
|
assign(pointers[event.pointerId || 0] || {}, getPointer(event, true));
|
1956
1797
|
}
|
1957
|
-
|
1958
1798
|
this.change(event);
|
1959
1799
|
},
|
1960
1800
|
cropEnd: function cropEnd(event) {
|
1961
1801
|
if (this.disabled) {
|
1962
1802
|
return;
|
1963
1803
|
}
|
1964
|
-
|
1965
1804
|
var action = this.action,
|
1966
|
-
|
1967
|
-
|
1805
|
+
pointers = this.pointers;
|
1968
1806
|
if (event.changedTouches) {
|
1969
1807
|
forEach(event.changedTouches, function (touch) {
|
1970
1808
|
delete pointers[touch.identifier];
|
@@ -1972,22 +1810,17 @@
|
|
1972
1810
|
} else {
|
1973
1811
|
delete pointers[event.pointerId || 0];
|
1974
1812
|
}
|
1975
|
-
|
1976
1813
|
if (!action) {
|
1977
1814
|
return;
|
1978
1815
|
}
|
1979
|
-
|
1980
1816
|
event.preventDefault();
|
1981
|
-
|
1982
1817
|
if (!Object.keys(pointers).length) {
|
1983
1818
|
this.action = '';
|
1984
1819
|
}
|
1985
|
-
|
1986
1820
|
if (this.cropping) {
|
1987
1821
|
this.cropping = false;
|
1988
1822
|
toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);
|
1989
1823
|
}
|
1990
|
-
|
1991
1824
|
dispatchEvent(this.element, EVENT_CROP_END, {
|
1992
1825
|
originalEvent: event,
|
1993
1826
|
action: action
|
@@ -1998,16 +1831,16 @@
|
|
1998
1831
|
var change = {
|
1999
1832
|
change: function change(event) {
|
2000
1833
|
var options = this.options,
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
1834
|
+
canvasData = this.canvasData,
|
1835
|
+
containerData = this.containerData,
|
1836
|
+
cropBoxData = this.cropBoxData,
|
1837
|
+
pointers = this.pointers;
|
2005
1838
|
var action = this.action;
|
2006
1839
|
var aspectRatio = options.aspectRatio;
|
2007
1840
|
var left = cropBoxData.left,
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
1841
|
+
top = cropBoxData.top,
|
1842
|
+
width = cropBoxData.width,
|
1843
|
+
height = cropBoxData.height;
|
2011
1844
|
var right = left + width;
|
2012
1845
|
var bottom = top + height;
|
2013
1846
|
var minLeft = 0;
|
@@ -2015,162 +1848,131 @@
|
|
2015
1848
|
var maxWidth = containerData.width;
|
2016
1849
|
var maxHeight = containerData.height;
|
2017
1850
|
var renderable = true;
|
2018
|
-
var offset;
|
1851
|
+
var offset;
|
2019
1852
|
|
1853
|
+
// Locking aspect ratio in "free mode" by holding shift key
|
2020
1854
|
if (!aspectRatio && event.shiftKey) {
|
2021
1855
|
aspectRatio = width && height ? width / height : 1;
|
2022
1856
|
}
|
2023
|
-
|
2024
1857
|
if (this.limited) {
|
2025
1858
|
minLeft = cropBoxData.minLeft;
|
2026
1859
|
minTop = cropBoxData.minTop;
|
2027
1860
|
maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width);
|
2028
1861
|
maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height);
|
2029
1862
|
}
|
2030
|
-
|
2031
1863
|
var pointer = pointers[Object.keys(pointers)[0]];
|
2032
1864
|
var range = {
|
2033
1865
|
x: pointer.endX - pointer.startX,
|
2034
1866
|
y: pointer.endY - pointer.startY
|
2035
1867
|
};
|
2036
|
-
|
2037
1868
|
var check = function check(side) {
|
2038
1869
|
switch (side) {
|
2039
1870
|
case ACTION_EAST:
|
2040
1871
|
if (right + range.x > maxWidth) {
|
2041
1872
|
range.x = maxWidth - right;
|
2042
1873
|
}
|
2043
|
-
|
2044
1874
|
break;
|
2045
|
-
|
2046
1875
|
case ACTION_WEST:
|
2047
1876
|
if (left + range.x < minLeft) {
|
2048
1877
|
range.x = minLeft - left;
|
2049
1878
|
}
|
2050
|
-
|
2051
1879
|
break;
|
2052
|
-
|
2053
1880
|
case ACTION_NORTH:
|
2054
1881
|
if (top + range.y < minTop) {
|
2055
1882
|
range.y = minTop - top;
|
2056
1883
|
}
|
2057
|
-
|
2058
1884
|
break;
|
2059
|
-
|
2060
1885
|
case ACTION_SOUTH:
|
2061
1886
|
if (bottom + range.y > maxHeight) {
|
2062
1887
|
range.y = maxHeight - bottom;
|
2063
1888
|
}
|
2064
|
-
|
2065
1889
|
break;
|
2066
1890
|
}
|
2067
1891
|
};
|
2068
|
-
|
2069
1892
|
switch (action) {
|
2070
1893
|
// Move crop box
|
2071
1894
|
case ACTION_ALL:
|
2072
1895
|
left += range.x;
|
2073
1896
|
top += range.y;
|
2074
1897
|
break;
|
2075
|
-
// Resize crop box
|
2076
1898
|
|
1899
|
+
// Resize crop box
|
2077
1900
|
case ACTION_EAST:
|
2078
1901
|
if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
|
2079
1902
|
renderable = false;
|
2080
1903
|
break;
|
2081
1904
|
}
|
2082
|
-
|
2083
1905
|
check(ACTION_EAST);
|
2084
1906
|
width += range.x;
|
2085
|
-
|
2086
1907
|
if (width < 0) {
|
2087
1908
|
action = ACTION_WEST;
|
2088
1909
|
width = -width;
|
2089
1910
|
left -= width;
|
2090
1911
|
}
|
2091
|
-
|
2092
1912
|
if (aspectRatio) {
|
2093
1913
|
height = width / aspectRatio;
|
2094
1914
|
top += (cropBoxData.height - height) / 2;
|
2095
1915
|
}
|
2096
|
-
|
2097
1916
|
break;
|
2098
|
-
|
2099
1917
|
case ACTION_NORTH:
|
2100
1918
|
if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) {
|
2101
1919
|
renderable = false;
|
2102
1920
|
break;
|
2103
1921
|
}
|
2104
|
-
|
2105
1922
|
check(ACTION_NORTH);
|
2106
1923
|
height -= range.y;
|
2107
1924
|
top += range.y;
|
2108
|
-
|
2109
1925
|
if (height < 0) {
|
2110
1926
|
action = ACTION_SOUTH;
|
2111
1927
|
height = -height;
|
2112
1928
|
top -= height;
|
2113
1929
|
}
|
2114
|
-
|
2115
1930
|
if (aspectRatio) {
|
2116
1931
|
width = height * aspectRatio;
|
2117
1932
|
left += (cropBoxData.width - width) / 2;
|
2118
1933
|
}
|
2119
|
-
|
2120
1934
|
break;
|
2121
|
-
|
2122
1935
|
case ACTION_WEST:
|
2123
1936
|
if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
|
2124
1937
|
renderable = false;
|
2125
1938
|
break;
|
2126
1939
|
}
|
2127
|
-
|
2128
1940
|
check(ACTION_WEST);
|
2129
1941
|
width -= range.x;
|
2130
1942
|
left += range.x;
|
2131
|
-
|
2132
1943
|
if (width < 0) {
|
2133
1944
|
action = ACTION_EAST;
|
2134
1945
|
width = -width;
|
2135
1946
|
left -= width;
|
2136
1947
|
}
|
2137
|
-
|
2138
1948
|
if (aspectRatio) {
|
2139
1949
|
height = width / aspectRatio;
|
2140
1950
|
top += (cropBoxData.height - height) / 2;
|
2141
1951
|
}
|
2142
|
-
|
2143
1952
|
break;
|
2144
|
-
|
2145
1953
|
case ACTION_SOUTH:
|
2146
1954
|
if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) {
|
2147
1955
|
renderable = false;
|
2148
1956
|
break;
|
2149
1957
|
}
|
2150
|
-
|
2151
1958
|
check(ACTION_SOUTH);
|
2152
1959
|
height += range.y;
|
2153
|
-
|
2154
1960
|
if (height < 0) {
|
2155
1961
|
action = ACTION_NORTH;
|
2156
1962
|
height = -height;
|
2157
1963
|
top -= height;
|
2158
1964
|
}
|
2159
|
-
|
2160
1965
|
if (aspectRatio) {
|
2161
1966
|
width = height * aspectRatio;
|
2162
1967
|
left += (cropBoxData.width - width) / 2;
|
2163
1968
|
}
|
2164
|
-
|
2165
1969
|
break;
|
2166
|
-
|
2167
1970
|
case ACTION_NORTH_EAST:
|
2168
1971
|
if (aspectRatio) {
|
2169
1972
|
if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {
|
2170
1973
|
renderable = false;
|
2171
1974
|
break;
|
2172
1975
|
}
|
2173
|
-
|
2174
1976
|
check(ACTION_NORTH);
|
2175
1977
|
height -= range.y;
|
2176
1978
|
top += range.y;
|
@@ -2178,7 +1980,6 @@
|
|
2178
1980
|
} else {
|
2179
1981
|
check(ACTION_NORTH);
|
2180
1982
|
check(ACTION_EAST);
|
2181
|
-
|
2182
1983
|
if (range.x >= 0) {
|
2183
1984
|
if (right < maxWidth) {
|
2184
1985
|
width += range.x;
|
@@ -2188,7 +1989,6 @@
|
|
2188
1989
|
} else {
|
2189
1990
|
width += range.x;
|
2190
1991
|
}
|
2191
|
-
|
2192
1992
|
if (range.y <= 0) {
|
2193
1993
|
if (top > minTop) {
|
2194
1994
|
height -= range.y;
|
@@ -2199,7 +1999,6 @@
|
|
2199
1999
|
top += range.y;
|
2200
2000
|
}
|
2201
2001
|
}
|
2202
|
-
|
2203
2002
|
if (width < 0 && height < 0) {
|
2204
2003
|
action = ACTION_SOUTH_WEST;
|
2205
2004
|
height = -height;
|
@@ -2215,16 +2014,13 @@
|
|
2215
2014
|
height = -height;
|
2216
2015
|
top -= height;
|
2217
2016
|
}
|
2218
|
-
|
2219
2017
|
break;
|
2220
|
-
|
2221
2018
|
case ACTION_NORTH_WEST:
|
2222
2019
|
if (aspectRatio) {
|
2223
2020
|
if (range.y <= 0 && (top <= minTop || left <= minLeft)) {
|
2224
2021
|
renderable = false;
|
2225
2022
|
break;
|
2226
2023
|
}
|
2227
|
-
|
2228
2024
|
check(ACTION_NORTH);
|
2229
2025
|
height -= range.y;
|
2230
2026
|
top += range.y;
|
@@ -2233,7 +2029,6 @@
|
|
2233
2029
|
} else {
|
2234
2030
|
check(ACTION_NORTH);
|
2235
2031
|
check(ACTION_WEST);
|
2236
|
-
|
2237
2032
|
if (range.x <= 0) {
|
2238
2033
|
if (left > minLeft) {
|
2239
2034
|
width -= range.x;
|
@@ -2245,7 +2040,6 @@
|
|
2245
2040
|
width -= range.x;
|
2246
2041
|
left += range.x;
|
2247
2042
|
}
|
2248
|
-
|
2249
2043
|
if (range.y <= 0) {
|
2250
2044
|
if (top > minTop) {
|
2251
2045
|
height -= range.y;
|
@@ -2256,7 +2050,6 @@
|
|
2256
2050
|
top += range.y;
|
2257
2051
|
}
|
2258
2052
|
}
|
2259
|
-
|
2260
2053
|
if (width < 0 && height < 0) {
|
2261
2054
|
action = ACTION_SOUTH_EAST;
|
2262
2055
|
height = -height;
|
@@ -2272,16 +2065,13 @@
|
|
2272
2065
|
height = -height;
|
2273
2066
|
top -= height;
|
2274
2067
|
}
|
2275
|
-
|
2276
2068
|
break;
|
2277
|
-
|
2278
2069
|
case ACTION_SOUTH_WEST:
|
2279
2070
|
if (aspectRatio) {
|
2280
2071
|
if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {
|
2281
2072
|
renderable = false;
|
2282
2073
|
break;
|
2283
2074
|
}
|
2284
|
-
|
2285
2075
|
check(ACTION_WEST);
|
2286
2076
|
width -= range.x;
|
2287
2077
|
left += range.x;
|
@@ -2289,7 +2079,6 @@
|
|
2289
2079
|
} else {
|
2290
2080
|
check(ACTION_SOUTH);
|
2291
2081
|
check(ACTION_WEST);
|
2292
|
-
|
2293
2082
|
if (range.x <= 0) {
|
2294
2083
|
if (left > minLeft) {
|
2295
2084
|
width -= range.x;
|
@@ -2301,7 +2090,6 @@
|
|
2301
2090
|
width -= range.x;
|
2302
2091
|
left += range.x;
|
2303
2092
|
}
|
2304
|
-
|
2305
2093
|
if (range.y >= 0) {
|
2306
2094
|
if (bottom < maxHeight) {
|
2307
2095
|
height += range.y;
|
@@ -2310,7 +2098,6 @@
|
|
2310
2098
|
height += range.y;
|
2311
2099
|
}
|
2312
2100
|
}
|
2313
|
-
|
2314
2101
|
if (width < 0 && height < 0) {
|
2315
2102
|
action = ACTION_NORTH_EAST;
|
2316
2103
|
height = -height;
|
@@ -2326,23 +2113,19 @@
|
|
2326
2113
|
height = -height;
|
2327
2114
|
top -= height;
|
2328
2115
|
}
|
2329
|
-
|
2330
2116
|
break;
|
2331
|
-
|
2332
2117
|
case ACTION_SOUTH_EAST:
|
2333
2118
|
if (aspectRatio) {
|
2334
2119
|
if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
|
2335
2120
|
renderable = false;
|
2336
2121
|
break;
|
2337
2122
|
}
|
2338
|
-
|
2339
2123
|
check(ACTION_EAST);
|
2340
2124
|
width += range.x;
|
2341
2125
|
height = width / aspectRatio;
|
2342
2126
|
} else {
|
2343
2127
|
check(ACTION_SOUTH);
|
2344
2128
|
check(ACTION_EAST);
|
2345
|
-
|
2346
2129
|
if (range.x >= 0) {
|
2347
2130
|
if (right < maxWidth) {
|
2348
2131
|
width += range.x;
|
@@ -2352,7 +2135,6 @@
|
|
2352
2135
|
} else {
|
2353
2136
|
width += range.x;
|
2354
2137
|
}
|
2355
|
-
|
2356
2138
|
if (range.y >= 0) {
|
2357
2139
|
if (bottom < maxHeight) {
|
2358
2140
|
height += range.y;
|
@@ -2361,7 +2143,6 @@
|
|
2361
2143
|
height += range.y;
|
2362
2144
|
}
|
2363
2145
|
}
|
2364
|
-
|
2365
2146
|
if (width < 0 && height < 0) {
|
2366
2147
|
action = ACTION_NORTH_WEST;
|
2367
2148
|
height = -height;
|
@@ -2377,58 +2158,51 @@
|
|
2377
2158
|
height = -height;
|
2378
2159
|
top -= height;
|
2379
2160
|
}
|
2380
|
-
|
2381
2161
|
break;
|
2382
|
-
// Move canvas
|
2383
2162
|
|
2163
|
+
// Move canvas
|
2384
2164
|
case ACTION_MOVE:
|
2385
2165
|
this.move(range.x, range.y);
|
2386
2166
|
renderable = false;
|
2387
2167
|
break;
|
2388
|
-
// Zoom canvas
|
2389
2168
|
|
2169
|
+
// Zoom canvas
|
2390
2170
|
case ACTION_ZOOM:
|
2391
2171
|
this.zoom(getMaxZoomRatio(pointers), event);
|
2392
2172
|
renderable = false;
|
2393
2173
|
break;
|
2394
|
-
// Create crop box
|
2395
2174
|
|
2175
|
+
// Create crop box
|
2396
2176
|
case ACTION_CROP:
|
2397
2177
|
if (!range.x || !range.y) {
|
2398
2178
|
renderable = false;
|
2399
2179
|
break;
|
2400
2180
|
}
|
2401
|
-
|
2402
2181
|
offset = getOffset(this.cropper);
|
2403
2182
|
left = pointer.startX - offset.left;
|
2404
2183
|
top = pointer.startY - offset.top;
|
2405
2184
|
width = cropBoxData.minWidth;
|
2406
2185
|
height = cropBoxData.minHeight;
|
2407
|
-
|
2408
2186
|
if (range.x > 0) {
|
2409
2187
|
action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;
|
2410
2188
|
} else if (range.x < 0) {
|
2411
2189
|
left -= width;
|
2412
2190
|
action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;
|
2413
2191
|
}
|
2414
|
-
|
2415
2192
|
if (range.y < 0) {
|
2416
2193
|
top -= height;
|
2417
|
-
}
|
2418
|
-
|
2194
|
+
}
|
2419
2195
|
|
2196
|
+
// Show the crop box if is hidden
|
2420
2197
|
if (!this.cropped) {
|
2421
2198
|
removeClass(this.cropBox, CLASS_HIDDEN);
|
2422
2199
|
this.cropped = true;
|
2423
|
-
|
2424
2200
|
if (this.limited) {
|
2425
2201
|
this.limitCropBox(true, true);
|
2426
2202
|
}
|
2427
2203
|
}
|
2428
|
-
|
2429
2204
|
break;
|
2430
2205
|
}
|
2431
|
-
|
2432
2206
|
if (renderable) {
|
2433
2207
|
cropBoxData.width = width;
|
2434
2208
|
cropBoxData.height = height;
|
@@ -2436,9 +2210,9 @@
|
|
2436
2210
|
cropBoxData.top = top;
|
2437
2211
|
this.action = action;
|
2438
2212
|
this.renderCropBox();
|
2439
|
-
}
|
2440
|
-
|
2213
|
+
}
|
2441
2214
|
|
2215
|
+
// Override
|
2442
2216
|
forEach(pointers, function (p) {
|
2443
2217
|
p.startX = p.endX;
|
2444
2218
|
p.startY = p.endY;
|
@@ -2452,15 +2226,12 @@
|
|
2452
2226
|
if (this.ready && !this.cropped && !this.disabled) {
|
2453
2227
|
this.cropped = true;
|
2454
2228
|
this.limitCropBox(true, true);
|
2455
|
-
|
2456
2229
|
if (this.options.modal) {
|
2457
2230
|
addClass(this.dragBox, CLASS_MODAL);
|
2458
2231
|
}
|
2459
|
-
|
2460
2232
|
removeClass(this.cropBox, CLASS_HIDDEN);
|
2461
2233
|
this.setCropBoxData(this.initialCropBoxData);
|
2462
2234
|
}
|
2463
|
-
|
2464
2235
|
return this;
|
2465
2236
|
},
|
2466
2237
|
// Reset the image and crop box to their initial states
|
@@ -2470,12 +2241,10 @@
|
|
2470
2241
|
this.canvasData = assign({}, this.initialCanvasData);
|
2471
2242
|
this.cropBoxData = assign({}, this.initialCropBoxData);
|
2472
2243
|
this.renderCanvas();
|
2473
|
-
|
2474
2244
|
if (this.cropped) {
|
2475
2245
|
this.renderCropBox();
|
2476
2246
|
}
|
2477
2247
|
}
|
2478
|
-
|
2479
2248
|
return this;
|
2480
2249
|
},
|
2481
2250
|
// Clear the crop box
|
@@ -2489,16 +2258,15 @@
|
|
2489
2258
|
});
|
2490
2259
|
this.cropped = false;
|
2491
2260
|
this.renderCropBox();
|
2492
|
-
this.limitCanvas(true, true);
|
2261
|
+
this.limitCanvas(true, true);
|
2493
2262
|
|
2263
|
+
// Render canvas after crop box rendered
|
2494
2264
|
this.renderCanvas();
|
2495
2265
|
removeClass(this.dragBox, CLASS_MODAL);
|
2496
2266
|
addClass(this.cropBox, CLASS_HIDDEN);
|
2497
2267
|
}
|
2498
|
-
|
2499
2268
|
return this;
|
2500
2269
|
},
|
2501
|
-
|
2502
2270
|
/**
|
2503
2271
|
* Replace the image's src and rebuild the cropper
|
2504
2272
|
* @param {string} url - The new URL.
|
@@ -2507,16 +2275,13 @@
|
|
2507
2275
|
*/
|
2508
2276
|
replace: function replace(url) {
|
2509
2277
|
var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
2510
|
-
|
2511
2278
|
if (!this.disabled && url) {
|
2512
2279
|
if (this.isImg) {
|
2513
2280
|
this.element.src = url;
|
2514
2281
|
}
|
2515
|
-
|
2516
2282
|
if (hasSameSize) {
|
2517
2283
|
this.url = url;
|
2518
2284
|
this.image.src = url;
|
2519
|
-
|
2520
2285
|
if (this.ready) {
|
2521
2286
|
this.viewBoxImage.src = url;
|
2522
2287
|
forEach(this.previews, function (element) {
|
@@ -2527,13 +2292,11 @@
|
|
2527
2292
|
if (this.isImg) {
|
2528
2293
|
this.replaced = true;
|
2529
2294
|
}
|
2530
|
-
|
2531
2295
|
this.options.data = null;
|
2532
2296
|
this.uncreate();
|
2533
2297
|
this.load(url);
|
2534
2298
|
}
|
2535
2299
|
}
|
2536
|
-
|
2537
2300
|
return this;
|
2538
2301
|
},
|
2539
2302
|
// Enable (unfreeze) the cropper
|
@@ -2542,7 +2305,6 @@
|
|
2542
2305
|
this.disabled = false;
|
2543
2306
|
removeClass(this.cropper, CLASS_DISABLED);
|
2544
2307
|
}
|
2545
|
-
|
2546
2308
|
return this;
|
2547
2309
|
},
|
2548
2310
|
// Disable (freeze) the cropper
|
@@ -2551,31 +2313,24 @@
|
|
2551
2313
|
this.disabled = true;
|
2552
2314
|
addClass(this.cropper, CLASS_DISABLED);
|
2553
2315
|
}
|
2554
|
-
|
2555
2316
|
return this;
|
2556
2317
|
},
|
2557
|
-
|
2558
2318
|
/**
|
2559
2319
|
* Destroy the cropper and remove the instance from the image
|
2560
2320
|
* @returns {Cropper} this
|
2561
2321
|
*/
|
2562
2322
|
destroy: function destroy() {
|
2563
2323
|
var element = this.element;
|
2564
|
-
|
2565
2324
|
if (!element[NAMESPACE]) {
|
2566
2325
|
return this;
|
2567
2326
|
}
|
2568
|
-
|
2569
2327
|
element[NAMESPACE] = undefined;
|
2570
|
-
|
2571
2328
|
if (this.isImg && this.replaced) {
|
2572
2329
|
element.src = this.originalUrl;
|
2573
2330
|
}
|
2574
|
-
|
2575
2331
|
this.uncreate();
|
2576
2332
|
return this;
|
2577
2333
|
},
|
2578
|
-
|
2579
2334
|
/**
|
2580
2335
|
* Move the canvas with relative offsets
|
2581
2336
|
* @param {number} offsetX - The relative offset distance on the x-axis.
|
@@ -2585,11 +2340,10 @@
|
|
2585
2340
|
move: function move(offsetX) {
|
2586
2341
|
var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX;
|
2587
2342
|
var _this$canvasData = this.canvasData,
|
2588
|
-
|
2589
|
-
|
2343
|
+
left = _this$canvasData.left,
|
2344
|
+
top = _this$canvasData.top;
|
2590
2345
|
return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY));
|
2591
2346
|
},
|
2592
|
-
|
2593
2347
|
/**
|
2594
2348
|
* Move the canvas to an absolute point
|
2595
2349
|
* @param {number} x - The x-axis coordinate.
|
@@ -2602,26 +2356,21 @@
|
|
2602
2356
|
var changed = false;
|
2603
2357
|
x = Number(x);
|
2604
2358
|
y = Number(y);
|
2605
|
-
|
2606
2359
|
if (this.ready && !this.disabled && this.options.movable) {
|
2607
2360
|
if (isNumber(x)) {
|
2608
2361
|
canvasData.left = x;
|
2609
2362
|
changed = true;
|
2610
2363
|
}
|
2611
|
-
|
2612
2364
|
if (isNumber(y)) {
|
2613
2365
|
canvasData.top = y;
|
2614
2366
|
changed = true;
|
2615
2367
|
}
|
2616
|
-
|
2617
2368
|
if (changed) {
|
2618
2369
|
this.renderCanvas(true);
|
2619
2370
|
}
|
2620
2371
|
}
|
2621
|
-
|
2622
2372
|
return this;
|
2623
2373
|
},
|
2624
|
-
|
2625
2374
|
/**
|
2626
2375
|
* Zoom the canvas with a relative ratio
|
2627
2376
|
* @param {number} ratio - The target ratio.
|
@@ -2631,16 +2380,13 @@
|
|
2631
2380
|
zoom: function zoom(ratio, _originalEvent) {
|
2632
2381
|
var canvasData = this.canvasData;
|
2633
2382
|
ratio = Number(ratio);
|
2634
|
-
|
2635
2383
|
if (ratio < 0) {
|
2636
2384
|
ratio = 1 / (1 - ratio);
|
2637
2385
|
} else {
|
2638
2386
|
ratio = 1 + ratio;
|
2639
2387
|
}
|
2640
|
-
|
2641
2388
|
return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent);
|
2642
2389
|
},
|
2643
|
-
|
2644
2390
|
/**
|
2645
2391
|
* Zoom the canvas to an absolute ratio
|
2646
2392
|
* @param {number} ratio - The target ratio.
|
@@ -2650,17 +2396,15 @@
|
|
2650
2396
|
*/
|
2651
2397
|
zoomTo: function zoomTo(ratio, pivot, _originalEvent) {
|
2652
2398
|
var options = this.options,
|
2653
|
-
|
2399
|
+
canvasData = this.canvasData;
|
2654
2400
|
var width = canvasData.width,
|
2655
|
-
|
2656
|
-
|
2657
|
-
|
2401
|
+
height = canvasData.height,
|
2402
|
+
naturalWidth = canvasData.naturalWidth,
|
2403
|
+
naturalHeight = canvasData.naturalHeight;
|
2658
2404
|
ratio = Number(ratio);
|
2659
|
-
|
2660
2405
|
if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {
|
2661
2406
|
var newWidth = naturalWidth * ratio;
|
2662
2407
|
var newHeight = naturalHeight * ratio;
|
2663
|
-
|
2664
2408
|
if (dispatchEvent(this.element, EVENT_ZOOM, {
|
2665
2409
|
ratio: ratio,
|
2666
2410
|
oldRatio: width / naturalWidth,
|
@@ -2668,15 +2412,15 @@
|
|
2668
2412
|
}) === false) {
|
2669
2413
|
return this;
|
2670
2414
|
}
|
2671
|
-
|
2672
2415
|
if (_originalEvent) {
|
2673
2416
|
var pointers = this.pointers;
|
2674
2417
|
var offset = getOffset(this.cropper);
|
2675
2418
|
var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
|
2676
2419
|
pageX: _originalEvent.pageX,
|
2677
2420
|
pageY: _originalEvent.pageY
|
2678
|
-
};
|
2421
|
+
};
|
2679
2422
|
|
2423
|
+
// Zoom from the triggering point of the event
|
2680
2424
|
canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width);
|
2681
2425
|
canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height);
|
2682
2426
|
} else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
|
@@ -2687,15 +2431,12 @@
|
|
2687
2431
|
canvasData.left -= (newWidth - width) / 2;
|
2688
2432
|
canvasData.top -= (newHeight - height) / 2;
|
2689
2433
|
}
|
2690
|
-
|
2691
2434
|
canvasData.width = newWidth;
|
2692
2435
|
canvasData.height = newHeight;
|
2693
2436
|
this.renderCanvas(true);
|
2694
2437
|
}
|
2695
|
-
|
2696
2438
|
return this;
|
2697
2439
|
},
|
2698
|
-
|
2699
2440
|
/**
|
2700
2441
|
* Rotate the canvas with a relative degree
|
2701
2442
|
* @param {number} degree - The rotate degree.
|
@@ -2704,7 +2445,6 @@
|
|
2704
2445
|
rotate: function rotate(degree) {
|
2705
2446
|
return this.rotateTo((this.imageData.rotate || 0) + Number(degree));
|
2706
2447
|
},
|
2707
|
-
|
2708
2448
|
/**
|
2709
2449
|
* Rotate the canvas to an absolute degree
|
2710
2450
|
* @param {number} degree - The rotate degree.
|
@@ -2712,15 +2452,12 @@
|
|
2712
2452
|
*/
|
2713
2453
|
rotateTo: function rotateTo(degree) {
|
2714
2454
|
degree = Number(degree);
|
2715
|
-
|
2716
2455
|
if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {
|
2717
2456
|
this.imageData.rotate = degree % 360;
|
2718
2457
|
this.renderCanvas(true, true);
|
2719
2458
|
}
|
2720
|
-
|
2721
2459
|
return this;
|
2722
2460
|
},
|
2723
|
-
|
2724
2461
|
/**
|
2725
2462
|
* Scale the image on the x-axis.
|
2726
2463
|
* @param {number} scaleX - The scale ratio on the x-axis.
|
@@ -2730,7 +2467,6 @@
|
|
2730
2467
|
var scaleY = this.imageData.scaleY;
|
2731
2468
|
return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1);
|
2732
2469
|
},
|
2733
|
-
|
2734
2470
|
/**
|
2735
2471
|
* Scale the image on the y-axis.
|
2736
2472
|
* @param {number} scaleY - The scale ratio on the y-axis.
|
@@ -2740,7 +2476,6 @@
|
|
2740
2476
|
var scaleX = this.imageData.scaleX;
|
2741
2477
|
return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY);
|
2742
2478
|
},
|
2743
|
-
|
2744
2479
|
/**
|
2745
2480
|
* Scale the image
|
2746
2481
|
* @param {number} scaleX - The scale ratio on the x-axis.
|
@@ -2753,26 +2488,21 @@
|
|
2753
2488
|
var transformed = false;
|
2754
2489
|
scaleX = Number(scaleX);
|
2755
2490
|
scaleY = Number(scaleY);
|
2756
|
-
|
2757
2491
|
if (this.ready && !this.disabled && this.options.scalable) {
|
2758
2492
|
if (isNumber(scaleX)) {
|
2759
2493
|
imageData.scaleX = scaleX;
|
2760
2494
|
transformed = true;
|
2761
2495
|
}
|
2762
|
-
|
2763
2496
|
if (isNumber(scaleY)) {
|
2764
2497
|
imageData.scaleY = scaleY;
|
2765
2498
|
transformed = true;
|
2766
2499
|
}
|
2767
|
-
|
2768
2500
|
if (transformed) {
|
2769
2501
|
this.renderCanvas(true, true);
|
2770
2502
|
}
|
2771
2503
|
}
|
2772
|
-
|
2773
2504
|
return this;
|
2774
2505
|
},
|
2775
|
-
|
2776
2506
|
/**
|
2777
2507
|
* Get the cropped area position and size data (base on the original image)
|
2778
2508
|
* @param {boolean} [rounded=false] - Indicate if round the data values or not.
|
@@ -2781,11 +2511,10 @@
|
|
2781
2511
|
getData: function getData() {
|
2782
2512
|
var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
2783
2513
|
var options = this.options,
|
2784
|
-
|
2785
|
-
|
2786
|
-
|
2514
|
+
imageData = this.imageData,
|
2515
|
+
canvasData = this.canvasData,
|
2516
|
+
cropBoxData = this.cropBoxData;
|
2787
2517
|
var data;
|
2788
|
-
|
2789
2518
|
if (this.ready && this.cropped) {
|
2790
2519
|
data = {
|
2791
2520
|
x: cropBoxData.left - canvasData.left,
|
@@ -2797,7 +2526,6 @@
|
|
2797
2526
|
forEach(data, function (n, i) {
|
2798
2527
|
data[i] = n / ratio;
|
2799
2528
|
});
|
2800
|
-
|
2801
2529
|
if (rounded) {
|
2802
2530
|
// In case rounding off leads to extra 1px in right or bottom border
|
2803
2531
|
// we should round the top-left corner and the dimension (#343).
|
@@ -2816,19 +2544,15 @@
|
|
2816
2544
|
height: 0
|
2817
2545
|
};
|
2818
2546
|
}
|
2819
|
-
|
2820
2547
|
if (options.rotatable) {
|
2821
2548
|
data.rotate = imageData.rotate || 0;
|
2822
2549
|
}
|
2823
|
-
|
2824
2550
|
if (options.scalable) {
|
2825
2551
|
data.scaleX = imageData.scaleX || 1;
|
2826
2552
|
data.scaleY = imageData.scaleY || 1;
|
2827
2553
|
}
|
2828
|
-
|
2829
2554
|
return data;
|
2830
2555
|
},
|
2831
|
-
|
2832
2556
|
/**
|
2833
2557
|
* Set the cropped area position and size with new data
|
2834
2558
|
* @param {Object} data - The new data.
|
@@ -2836,60 +2560,47 @@
|
|
2836
2560
|
*/
|
2837
2561
|
setData: function setData(data) {
|
2838
2562
|
var options = this.options,
|
2839
|
-
|
2840
|
-
|
2563
|
+
imageData = this.imageData,
|
2564
|
+
canvasData = this.canvasData;
|
2841
2565
|
var cropBoxData = {};
|
2842
|
-
|
2843
2566
|
if (this.ready && !this.disabled && isPlainObject(data)) {
|
2844
2567
|
var transformed = false;
|
2845
|
-
|
2846
2568
|
if (options.rotatable) {
|
2847
2569
|
if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {
|
2848
2570
|
imageData.rotate = data.rotate;
|
2849
2571
|
transformed = true;
|
2850
2572
|
}
|
2851
2573
|
}
|
2852
|
-
|
2853
2574
|
if (options.scalable) {
|
2854
2575
|
if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {
|
2855
2576
|
imageData.scaleX = data.scaleX;
|
2856
2577
|
transformed = true;
|
2857
2578
|
}
|
2858
|
-
|
2859
2579
|
if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {
|
2860
2580
|
imageData.scaleY = data.scaleY;
|
2861
2581
|
transformed = true;
|
2862
2582
|
}
|
2863
2583
|
}
|
2864
|
-
|
2865
2584
|
if (transformed) {
|
2866
2585
|
this.renderCanvas(true, true);
|
2867
2586
|
}
|
2868
|
-
|
2869
2587
|
var ratio = imageData.width / imageData.naturalWidth;
|
2870
|
-
|
2871
2588
|
if (isNumber(data.x)) {
|
2872
2589
|
cropBoxData.left = data.x * ratio + canvasData.left;
|
2873
2590
|
}
|
2874
|
-
|
2875
2591
|
if (isNumber(data.y)) {
|
2876
2592
|
cropBoxData.top = data.y * ratio + canvasData.top;
|
2877
2593
|
}
|
2878
|
-
|
2879
2594
|
if (isNumber(data.width)) {
|
2880
2595
|
cropBoxData.width = data.width * ratio;
|
2881
2596
|
}
|
2882
|
-
|
2883
2597
|
if (isNumber(data.height)) {
|
2884
2598
|
cropBoxData.height = data.height * ratio;
|
2885
2599
|
}
|
2886
|
-
|
2887
2600
|
this.setCropBoxData(cropBoxData);
|
2888
2601
|
}
|
2889
|
-
|
2890
2602
|
return this;
|
2891
2603
|
},
|
2892
|
-
|
2893
2604
|
/**
|
2894
2605
|
* Get the container size data.
|
2895
2606
|
* @returns {Object} The result container data.
|
@@ -2897,7 +2608,6 @@
|
|
2897
2608
|
getContainerData: function getContainerData() {
|
2898
2609
|
return this.ready ? assign({}, this.containerData) : {};
|
2899
2610
|
},
|
2900
|
-
|
2901
2611
|
/**
|
2902
2612
|
* Get the image position and size data.
|
2903
2613
|
* @returns {Object} The result image data.
|
@@ -2905,7 +2615,6 @@
|
|
2905
2615
|
getImageData: function getImageData() {
|
2906
2616
|
return this.sized ? assign({}, this.imageData) : {};
|
2907
2617
|
},
|
2908
|
-
|
2909
2618
|
/**
|
2910
2619
|
* Get the canvas position and size data.
|
2911
2620
|
* @returns {Object} The result canvas data.
|
@@ -2913,16 +2622,13 @@
|
|
2913
2622
|
getCanvasData: function getCanvasData() {
|
2914
2623
|
var canvasData = this.canvasData;
|
2915
2624
|
var data = {};
|
2916
|
-
|
2917
2625
|
if (this.ready) {
|
2918
2626
|
forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) {
|
2919
2627
|
data[n] = canvasData[n];
|
2920
2628
|
});
|
2921
2629
|
}
|
2922
|
-
|
2923
2630
|
return data;
|
2924
2631
|
},
|
2925
|
-
|
2926
2632
|
/**
|
2927
2633
|
* Set the canvas position and size with new data.
|
2928
2634
|
* @param {Object} data - The new canvas data.
|
@@ -2931,16 +2637,13 @@
|
|
2931
2637
|
setCanvasData: function setCanvasData(data) {
|
2932
2638
|
var canvasData = this.canvasData;
|
2933
2639
|
var aspectRatio = canvasData.aspectRatio;
|
2934
|
-
|
2935
2640
|
if (this.ready && !this.disabled && isPlainObject(data)) {
|
2936
2641
|
if (isNumber(data.left)) {
|
2937
2642
|
canvasData.left = data.left;
|
2938
2643
|
}
|
2939
|
-
|
2940
2644
|
if (isNumber(data.top)) {
|
2941
2645
|
canvasData.top = data.top;
|
2942
2646
|
}
|
2943
|
-
|
2944
2647
|
if (isNumber(data.width)) {
|
2945
2648
|
canvasData.width = data.width;
|
2946
2649
|
canvasData.height = data.width / aspectRatio;
|
@@ -2948,13 +2651,10 @@
|
|
2948
2651
|
canvasData.height = data.height;
|
2949
2652
|
canvasData.width = data.height * aspectRatio;
|
2950
2653
|
}
|
2951
|
-
|
2952
2654
|
this.renderCanvas(true);
|
2953
2655
|
}
|
2954
|
-
|
2955
2656
|
return this;
|
2956
2657
|
},
|
2957
|
-
|
2958
2658
|
/**
|
2959
2659
|
* Get the crop box position and size data.
|
2960
2660
|
* @returns {Object} The result crop box data.
|
@@ -2962,7 +2662,6 @@
|
|
2962
2662
|
getCropBoxData: function getCropBoxData() {
|
2963
2663
|
var cropBoxData = this.cropBoxData;
|
2964
2664
|
var data;
|
2965
|
-
|
2966
2665
|
if (this.ready && this.cropped) {
|
2967
2666
|
data = {
|
2968
2667
|
left: cropBoxData.left,
|
@@ -2971,10 +2670,8 @@
|
|
2971
2670
|
height: cropBoxData.height
|
2972
2671
|
};
|
2973
2672
|
}
|
2974
|
-
|
2975
2673
|
return data || {};
|
2976
2674
|
},
|
2977
|
-
|
2978
2675
|
/**
|
2979
2676
|
* Set the crop box position and size with new data.
|
2980
2677
|
* @param {Object} data - The new crop box data.
|
@@ -2985,26 +2682,21 @@
|
|
2985
2682
|
var aspectRatio = this.options.aspectRatio;
|
2986
2683
|
var widthChanged;
|
2987
2684
|
var heightChanged;
|
2988
|
-
|
2989
2685
|
if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {
|
2990
2686
|
if (isNumber(data.left)) {
|
2991
2687
|
cropBoxData.left = data.left;
|
2992
2688
|
}
|
2993
|
-
|
2994
2689
|
if (isNumber(data.top)) {
|
2995
2690
|
cropBoxData.top = data.top;
|
2996
2691
|
}
|
2997
|
-
|
2998
2692
|
if (isNumber(data.width) && data.width !== cropBoxData.width) {
|
2999
2693
|
widthChanged = true;
|
3000
2694
|
cropBoxData.width = data.width;
|
3001
2695
|
}
|
3002
|
-
|
3003
2696
|
if (isNumber(data.height) && data.height !== cropBoxData.height) {
|
3004
2697
|
heightChanged = true;
|
3005
2698
|
cropBoxData.height = data.height;
|
3006
2699
|
}
|
3007
|
-
|
3008
2700
|
if (aspectRatio) {
|
3009
2701
|
if (widthChanged) {
|
3010
2702
|
cropBoxData.height = cropBoxData.width / aspectRatio;
|
@@ -3012,13 +2704,10 @@
|
|
3012
2704
|
cropBoxData.width = cropBoxData.height * aspectRatio;
|
3013
2705
|
}
|
3014
2706
|
}
|
3015
|
-
|
3016
2707
|
this.renderCropBox();
|
3017
2708
|
}
|
3018
|
-
|
3019
2709
|
return this;
|
3020
2710
|
},
|
3021
|
-
|
3022
2711
|
/**
|
3023
2712
|
* Get a canvas drawn the cropped image.
|
3024
2713
|
* @param {Object} [options={}] - The config options.
|
@@ -3026,33 +2715,28 @@
|
|
3026
2715
|
*/
|
3027
2716
|
getCroppedCanvas: function getCroppedCanvas() {
|
3028
2717
|
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
3029
|
-
|
3030
2718
|
if (!this.ready || !window.HTMLCanvasElement) {
|
3031
2719
|
return null;
|
3032
2720
|
}
|
3033
|
-
|
3034
2721
|
var canvasData = this.canvasData;
|
3035
|
-
var source = getSourceCanvas(this.image, this.imageData, canvasData, options);
|
2722
|
+
var source = getSourceCanvas(this.image, this.imageData, canvasData, options);
|
3036
2723
|
|
2724
|
+
// Returns the source canvas if it is not cropped.
|
3037
2725
|
if (!this.cropped) {
|
3038
2726
|
return source;
|
3039
2727
|
}
|
3040
|
-
|
3041
2728
|
var _this$getData = this.getData(),
|
3042
|
-
|
3043
|
-
|
3044
|
-
|
3045
|
-
|
3046
|
-
|
2729
|
+
initialX = _this$getData.x,
|
2730
|
+
initialY = _this$getData.y,
|
2731
|
+
initialWidth = _this$getData.width,
|
2732
|
+
initialHeight = _this$getData.height;
|
3047
2733
|
var ratio = source.width / Math.floor(canvasData.naturalWidth);
|
3048
|
-
|
3049
2734
|
if (ratio !== 1) {
|
3050
2735
|
initialX *= ratio;
|
3051
2736
|
initialY *= ratio;
|
3052
2737
|
initialWidth *= ratio;
|
3053
2738
|
initialHeight *= ratio;
|
3054
2739
|
}
|
3055
|
-
|
3056
2740
|
var aspectRatio = initialWidth / initialHeight;
|
3057
2741
|
var maxSizes = getAdjustedSizes({
|
3058
2742
|
aspectRatio: aspectRatio,
|
@@ -3064,15 +2748,13 @@
|
|
3064
2748
|
width: options.minWidth || 0,
|
3065
2749
|
height: options.minHeight || 0
|
3066
2750
|
}, 'cover');
|
3067
|
-
|
3068
2751
|
var _getAdjustedSizes = getAdjustedSizes({
|
3069
|
-
|
3070
|
-
|
3071
|
-
|
3072
|
-
|
3073
|
-
|
3074
|
-
|
3075
|
-
|
2752
|
+
aspectRatio: aspectRatio,
|
2753
|
+
width: options.width || (ratio !== 1 ? source.width : initialWidth),
|
2754
|
+
height: options.height || (ratio !== 1 ? source.height : initialHeight)
|
2755
|
+
}),
|
2756
|
+
width = _getAdjustedSizes.width,
|
2757
|
+
height = _getAdjustedSizes.height;
|
3076
2758
|
width = Math.min(maxSizes.width, Math.max(minSizes.width, width));
|
3077
2759
|
height = Math.min(maxSizes.height, Math.max(minSizes.height, height));
|
3078
2760
|
var canvas = document.createElement('canvas');
|
@@ -3082,28 +2764,28 @@
|
|
3082
2764
|
context.fillStyle = options.fillColor || 'transparent';
|
3083
2765
|
context.fillRect(0, 0, width, height);
|
3084
2766
|
var _options$imageSmoothi = options.imageSmoothingEnabled,
|
3085
|
-
|
3086
|
-
|
2767
|
+
imageSmoothingEnabled = _options$imageSmoothi === void 0 ? true : _options$imageSmoothi,
|
2768
|
+
imageSmoothingQuality = options.imageSmoothingQuality;
|
3087
2769
|
context.imageSmoothingEnabled = imageSmoothingEnabled;
|
3088
|
-
|
3089
2770
|
if (imageSmoothingQuality) {
|
3090
2771
|
context.imageSmoothingQuality = imageSmoothingQuality;
|
3091
|
-
}
|
3092
|
-
|
2772
|
+
}
|
3093
2773
|
|
2774
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
|
3094
2775
|
var sourceWidth = source.width;
|
3095
|
-
var sourceHeight = source.height;
|
2776
|
+
var sourceHeight = source.height;
|
3096
2777
|
|
2778
|
+
// Source canvas parameters
|
3097
2779
|
var srcX = initialX;
|
3098
2780
|
var srcY = initialY;
|
3099
2781
|
var srcWidth;
|
3100
|
-
var srcHeight;
|
2782
|
+
var srcHeight;
|
3101
2783
|
|
2784
|
+
// Destination canvas parameters
|
3102
2785
|
var dstX;
|
3103
2786
|
var dstY;
|
3104
2787
|
var dstWidth;
|
3105
2788
|
var dstHeight;
|
3106
|
-
|
3107
2789
|
if (srcX <= -initialWidth || srcX > sourceWidth) {
|
3108
2790
|
srcX = 0;
|
3109
2791
|
srcWidth = 0;
|
@@ -3119,7 +2801,6 @@
|
|
3119
2801
|
srcWidth = Math.min(initialWidth, sourceWidth - srcX);
|
3120
2802
|
dstWidth = srcWidth;
|
3121
2803
|
}
|
3122
|
-
|
3123
2804
|
if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {
|
3124
2805
|
srcY = 0;
|
3125
2806
|
srcHeight = 0;
|
@@ -3135,22 +2816,21 @@
|
|
3135
2816
|
srcHeight = Math.min(initialHeight, sourceHeight - srcY);
|
3136
2817
|
dstHeight = srcHeight;
|
3137
2818
|
}
|
2819
|
+
var params = [srcX, srcY, srcWidth, srcHeight];
|
3138
2820
|
|
3139
|
-
|
3140
|
-
|
2821
|
+
// Avoid "IndexSizeError"
|
3141
2822
|
if (dstWidth > 0 && dstHeight > 0) {
|
3142
2823
|
var scale = width / initialWidth;
|
3143
2824
|
params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale);
|
3144
|
-
}
|
3145
|
-
// https://github.com/fengyuanchen/cropper/issues/476
|
3146
|
-
|
2825
|
+
}
|
3147
2826
|
|
2827
|
+
// All the numerical parameters should be integer for `drawImage`
|
2828
|
+
// https://github.com/fengyuanchen/cropper/issues/476
|
3148
2829
|
context.drawImage.apply(context, [source].concat(_toConsumableArray(params.map(function (param) {
|
3149
2830
|
return Math.floor(normalizeDecimalNumber(param));
|
3150
2831
|
}))));
|
3151
2832
|
return canvas;
|
3152
2833
|
},
|
3153
|
-
|
3154
2834
|
/**
|
3155
2835
|
* Change the aspect ratio of the crop box.
|
3156
2836
|
* @param {number} aspectRatio - The new aspect ratio.
|
@@ -3158,23 +2838,18 @@
|
|
3158
2838
|
*/
|
3159
2839
|
setAspectRatio: function setAspectRatio(aspectRatio) {
|
3160
2840
|
var options = this.options;
|
3161
|
-
|
3162
2841
|
if (!this.disabled && !isUndefined(aspectRatio)) {
|
3163
2842
|
// 0 -> NaN
|
3164
2843
|
options.aspectRatio = Math.max(0, aspectRatio) || NaN;
|
3165
|
-
|
3166
2844
|
if (this.ready) {
|
3167
2845
|
this.initCropBox();
|
3168
|
-
|
3169
2846
|
if (this.cropped) {
|
3170
2847
|
this.renderCropBox();
|
3171
2848
|
}
|
3172
2849
|
}
|
3173
2850
|
}
|
3174
|
-
|
3175
2851
|
return this;
|
3176
2852
|
},
|
3177
|
-
|
3178
2853
|
/**
|
3179
2854
|
* Change the drag mode.
|
3180
2855
|
* @param {string} mode - The new drag mode.
|
@@ -3182,9 +2857,8 @@
|
|
3182
2857
|
*/
|
3183
2858
|
setDragMode: function setDragMode(mode) {
|
3184
2859
|
var options = this.options,
|
3185
|
-
|
3186
|
-
|
3187
|
-
|
2860
|
+
dragBox = this.dragBox,
|
2861
|
+
face = this.face;
|
3188
2862
|
if (this.ready && !this.disabled) {
|
3189
2863
|
var croppable = mode === DRAG_MODE_CROP;
|
3190
2864
|
var movable = options.movable && mode === DRAG_MODE_MOVE;
|
@@ -3193,7 +2867,6 @@
|
|
3193
2867
|
setData(dragBox, DATA_ACTION, mode);
|
3194
2868
|
toggleClass(dragBox, CLASS_CROP, croppable);
|
3195
2869
|
toggleClass(dragBox, CLASS_MOVE, movable);
|
3196
|
-
|
3197
2870
|
if (!options.cropBoxMovable) {
|
3198
2871
|
// Sync drag mode to crop box when it is not movable
|
3199
2872
|
setData(face, DATA_ACTION, mode);
|
@@ -3201,13 +2874,11 @@
|
|
3201
2874
|
toggleClass(face, CLASS_MOVE, movable);
|
3202
2875
|
}
|
3203
2876
|
}
|
3204
|
-
|
3205
2877
|
return this;
|
3206
2878
|
}
|
3207
2879
|
};
|
3208
2880
|
|
3209
2881
|
var AnotherCropper = WINDOW.Cropper;
|
3210
|
-
|
3211
2882
|
var Cropper = /*#__PURE__*/function () {
|
3212
2883
|
/**
|
3213
2884
|
* Create a new Cropper.
|
@@ -3216,13 +2887,10 @@
|
|
3216
2887
|
*/
|
3217
2888
|
function Cropper(element) {
|
3218
2889
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
3219
|
-
|
3220
2890
|
_classCallCheck(this, Cropper);
|
3221
|
-
|
3222
2891
|
if (!element || !REGEXP_TAG_NAME.test(element.tagName)) {
|
3223
2892
|
throw new Error('The first argument is required and must be an <img> or <canvas> element.');
|
3224
2893
|
}
|
3225
|
-
|
3226
2894
|
this.element = element;
|
3227
2895
|
this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
|
3228
2896
|
this.cropped = false;
|
@@ -3235,63 +2903,57 @@
|
|
3235
2903
|
this.sizing = false;
|
3236
2904
|
this.init();
|
3237
2905
|
}
|
3238
|
-
|
3239
2906
|
_createClass(Cropper, [{
|
3240
2907
|
key: "init",
|
3241
2908
|
value: function init() {
|
3242
2909
|
var element = this.element;
|
3243
2910
|
var tagName = element.tagName.toLowerCase();
|
3244
2911
|
var url;
|
3245
|
-
|
3246
2912
|
if (element[NAMESPACE]) {
|
3247
2913
|
return;
|
3248
2914
|
}
|
3249
|
-
|
3250
2915
|
element[NAMESPACE] = this;
|
3251
|
-
|
3252
2916
|
if (tagName === 'img') {
|
3253
|
-
this.isImg = true;
|
2917
|
+
this.isImg = true;
|
3254
2918
|
|
2919
|
+
// e.g.: "img/picture.jpg"
|
3255
2920
|
url = element.getAttribute('src') || '';
|
3256
|
-
this.originalUrl = url;
|
2921
|
+
this.originalUrl = url;
|
3257
2922
|
|
2923
|
+
// Stop when it's a blank image
|
3258
2924
|
if (!url) {
|
3259
2925
|
return;
|
3260
|
-
}
|
3261
|
-
|
2926
|
+
}
|
3262
2927
|
|
2928
|
+
// e.g.: "https://example.com/img/picture.jpg"
|
3263
2929
|
url = element.src;
|
3264
2930
|
} else if (tagName === 'canvas' && window.HTMLCanvasElement) {
|
3265
2931
|
url = element.toDataURL();
|
3266
2932
|
}
|
3267
|
-
|
3268
2933
|
this.load(url);
|
3269
2934
|
}
|
3270
2935
|
}, {
|
3271
2936
|
key: "load",
|
3272
2937
|
value: function load(url) {
|
3273
2938
|
var _this = this;
|
3274
|
-
|
3275
2939
|
if (!url) {
|
3276
2940
|
return;
|
3277
2941
|
}
|
3278
|
-
|
3279
2942
|
this.url = url;
|
3280
2943
|
this.imageData = {};
|
3281
2944
|
var element = this.element,
|
3282
|
-
|
3283
|
-
|
2945
|
+
options = this.options;
|
3284
2946
|
if (!options.rotatable && !options.scalable) {
|
3285
2947
|
options.checkOrientation = false;
|
3286
|
-
}
|
3287
|
-
|
2948
|
+
}
|
3288
2949
|
|
2950
|
+
// Only IE10+ supports Typed Arrays
|
3289
2951
|
if (!options.checkOrientation || !window.ArrayBuffer) {
|
3290
2952
|
this.clone();
|
3291
2953
|
return;
|
3292
|
-
}
|
3293
|
-
|
2954
|
+
}
|
3294
2955
|
|
2956
|
+
// Detect the mime type of the image directly if it is a Data URL
|
3295
2957
|
if (REGEXP_DATA_URL.test(url)) {
|
3296
2958
|
// Read ArrayBuffer from Data URL of JPEG images directly for better performance
|
3297
2959
|
if (REGEXP_DATA_URL_JPEG.test(url)) {
|
@@ -3301,46 +2963,43 @@
|
|
3301
2963
|
// the rest types of Data URLs are not necessary to check orientation at all.
|
3302
2964
|
this.clone();
|
3303
2965
|
}
|
3304
|
-
|
3305
2966
|
return;
|
3306
|
-
}
|
3307
|
-
// 2. Load the image as ArrayBuffer for reading orientation if its a JPEG image.
|
3308
|
-
|
2967
|
+
}
|
3309
2968
|
|
2969
|
+
// 1. Detect the mime type of the image by a XMLHttpRequest.
|
2970
|
+
// 2. Load the image as ArrayBuffer for reading orientation if its a JPEG image.
|
3310
2971
|
var xhr = new XMLHttpRequest();
|
3311
2972
|
var clone = this.clone.bind(this);
|
3312
2973
|
this.reloading = true;
|
3313
|
-
this.xhr = xhr;
|
2974
|
+
this.xhr = xhr;
|
2975
|
+
|
2976
|
+
// 1. Cross origin requests are only supported for protocol schemes:
|
3314
2977
|
// http, https, data, chrome, chrome-extension.
|
3315
2978
|
// 2. Access to XMLHttpRequest from a Data URL will be blocked by CORS policy
|
3316
2979
|
// in some browsers as IE11 and Safari.
|
3317
|
-
|
3318
2980
|
xhr.onabort = clone;
|
3319
2981
|
xhr.onerror = clone;
|
3320
2982
|
xhr.ontimeout = clone;
|
3321
|
-
|
3322
2983
|
xhr.onprogress = function () {
|
3323
2984
|
// Abort the request directly if it not a JPEG image for better performance
|
3324
2985
|
if (xhr.getResponseHeader('content-type') !== MIME_TYPE_JPEG) {
|
3325
2986
|
xhr.abort();
|
3326
2987
|
}
|
3327
2988
|
};
|
3328
|
-
|
3329
2989
|
xhr.onload = function () {
|
3330
2990
|
_this.read(xhr.response);
|
3331
2991
|
};
|
3332
|
-
|
3333
2992
|
xhr.onloadend = function () {
|
3334
2993
|
_this.reloading = false;
|
3335
2994
|
_this.xhr = null;
|
3336
|
-
};
|
3337
|
-
|
2995
|
+
};
|
3338
2996
|
|
2997
|
+
// Bust cache when there is a "crossOrigin" property to avoid browser cache error
|
3339
2998
|
if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {
|
3340
2999
|
url = addTimestamp(url);
|
3341
|
-
}
|
3342
|
-
|
3000
|
+
}
|
3343
3001
|
|
3002
|
+
// The third parameter is required for avoiding side-effect (#682)
|
3344
3003
|
xhr.open('GET', url, true);
|
3345
3004
|
xhr.responseType = 'arraybuffer';
|
3346
3005
|
xhr.withCredentials = element.crossOrigin === 'use-credentials';
|
@@ -3350,61 +3009,52 @@
|
|
3350
3009
|
key: "read",
|
3351
3010
|
value: function read(arrayBuffer) {
|
3352
3011
|
var options = this.options,
|
3353
|
-
|
3354
|
-
// as some iOS browsers will render image with its orientation
|
3012
|
+
imageData = this.imageData;
|
3355
3013
|
|
3014
|
+
// Reset the orientation value to its default value 1
|
3015
|
+
// as some iOS browsers will render image with its orientation
|
3356
3016
|
var orientation = resetAndGetOrientation(arrayBuffer);
|
3357
3017
|
var rotate = 0;
|
3358
3018
|
var scaleX = 1;
|
3359
3019
|
var scaleY = 1;
|
3360
|
-
|
3361
3020
|
if (orientation > 1) {
|
3362
3021
|
// Generate a new URL which has the default orientation value
|
3363
3022
|
this.url = arrayBufferToDataURL(arrayBuffer, MIME_TYPE_JPEG);
|
3364
|
-
|
3365
3023
|
var _parseOrientation = parseOrientation(orientation);
|
3366
|
-
|
3367
3024
|
rotate = _parseOrientation.rotate;
|
3368
3025
|
scaleX = _parseOrientation.scaleX;
|
3369
3026
|
scaleY = _parseOrientation.scaleY;
|
3370
3027
|
}
|
3371
|
-
|
3372
3028
|
if (options.rotatable) {
|
3373
3029
|
imageData.rotate = rotate;
|
3374
3030
|
}
|
3375
|
-
|
3376
3031
|
if (options.scalable) {
|
3377
3032
|
imageData.scaleX = scaleX;
|
3378
3033
|
imageData.scaleY = scaleY;
|
3379
3034
|
}
|
3380
|
-
|
3381
3035
|
this.clone();
|
3382
3036
|
}
|
3383
3037
|
}, {
|
3384
3038
|
key: "clone",
|
3385
3039
|
value: function clone() {
|
3386
3040
|
var element = this.element,
|
3387
|
-
|
3041
|
+
url = this.url;
|
3388
3042
|
var crossOrigin = element.crossOrigin;
|
3389
3043
|
var crossOriginUrl = url;
|
3390
|
-
|
3391
3044
|
if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {
|
3392
3045
|
if (!crossOrigin) {
|
3393
3046
|
crossOrigin = 'anonymous';
|
3394
|
-
}
|
3395
|
-
|
3047
|
+
}
|
3396
3048
|
|
3049
|
+
// Bust cache when there is not a "crossOrigin" property (#519)
|
3397
3050
|
crossOriginUrl = addTimestamp(url);
|
3398
3051
|
}
|
3399
|
-
|
3400
3052
|
this.crossOrigin = crossOrigin;
|
3401
3053
|
this.crossOriginUrl = crossOriginUrl;
|
3402
3054
|
var image = document.createElement('img');
|
3403
|
-
|
3404
3055
|
if (crossOrigin) {
|
3405
3056
|
image.crossOrigin = crossOrigin;
|
3406
3057
|
}
|
3407
|
-
|
3408
3058
|
image.src = crossOriginUrl || url;
|
3409
3059
|
image.alt = element.alt || 'The image to crop';
|
3410
3060
|
this.image = image;
|
@@ -3417,15 +3067,14 @@
|
|
3417
3067
|
key: "start",
|
3418
3068
|
value: function start() {
|
3419
3069
|
var _this2 = this;
|
3420
|
-
|
3421
3070
|
var image = this.image;
|
3422
3071
|
image.onload = null;
|
3423
3072
|
image.onerror = null;
|
3424
|
-
this.sizing = true;
|
3425
|
-
// such as Safari for iOS, Chrome for iOS, and in-app browsers.
|
3073
|
+
this.sizing = true;
|
3426
3074
|
|
3075
|
+
// Match all browsers that use WebKit as the layout engine in iOS devices,
|
3076
|
+
// such as Safari for iOS, Chrome for iOS, and in-app browsers.
|
3427
3077
|
var isIOSWebKit = WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent);
|
3428
|
-
|
3429
3078
|
var done = function done(naturalWidth, naturalHeight) {
|
3430
3079
|
assign(_this2.imageData, {
|
3431
3080
|
naturalWidth: naturalWidth,
|
@@ -3435,31 +3084,27 @@
|
|
3435
3084
|
_this2.initialImageData = assign({}, _this2.imageData);
|
3436
3085
|
_this2.sizing = false;
|
3437
3086
|
_this2.sized = true;
|
3438
|
-
|
3439
3087
|
_this2.build();
|
3440
|
-
};
|
3441
|
-
|
3088
|
+
};
|
3442
3089
|
|
3090
|
+
// Most modern browsers (excepts iOS WebKit)
|
3443
3091
|
if (image.naturalWidth && !isIOSWebKit) {
|
3444
3092
|
done(image.naturalWidth, image.naturalHeight);
|
3445
3093
|
return;
|
3446
3094
|
}
|
3447
|
-
|
3448
3095
|
var sizingImage = document.createElement('img');
|
3449
3096
|
var body = document.body || document.documentElement;
|
3450
3097
|
this.sizingImage = sizingImage;
|
3451
|
-
|
3452
3098
|
sizingImage.onload = function () {
|
3453
3099
|
done(sizingImage.width, sizingImage.height);
|
3454
|
-
|
3455
3100
|
if (!isIOSWebKit) {
|
3456
3101
|
body.removeChild(sizingImage);
|
3457
3102
|
}
|
3458
3103
|
};
|
3104
|
+
sizingImage.src = image.src;
|
3459
3105
|
|
3460
|
-
|
3106
|
+
// iOS WebKit will convert the image automatically
|
3461
3107
|
// with its orientation once append it into DOM (#279)
|
3462
|
-
|
3463
3108
|
if (!isIOSWebKit) {
|
3464
3109
|
sizingImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
|
3465
3110
|
body.appendChild(sizingImage);
|
@@ -3480,11 +3125,11 @@
|
|
3480
3125
|
if (!this.sized || this.ready) {
|
3481
3126
|
return;
|
3482
3127
|
}
|
3483
|
-
|
3484
3128
|
var element = this.element,
|
3485
|
-
|
3486
|
-
|
3129
|
+
options = this.options,
|
3130
|
+
image = this.image;
|
3487
3131
|
|
3132
|
+
// Create cropper elements
|
3488
3133
|
var container = element.parentNode;
|
3489
3134
|
var template = document.createElement('div');
|
3490
3135
|
template.innerHTML = TEMPLATE;
|
@@ -3500,65 +3145,54 @@
|
|
3500
3145
|
this.cropBox = cropBox;
|
3501
3146
|
this.viewBox = cropper.querySelector(".".concat(NAMESPACE, "-view-box"));
|
3502
3147
|
this.face = face;
|
3503
|
-
canvas.appendChild(image);
|
3504
|
-
|
3505
|
-
addClass(element, CLASS_HIDDEN); // Inserts the cropper after to the current image
|
3148
|
+
canvas.appendChild(image);
|
3506
3149
|
|
3507
|
-
|
3150
|
+
// Hide the original image
|
3151
|
+
addClass(element, CLASS_HIDDEN);
|
3508
3152
|
|
3509
|
-
|
3510
|
-
|
3511
|
-
}
|
3153
|
+
// Inserts the cropper after to the current image
|
3154
|
+
container.insertBefore(cropper, element.nextSibling);
|
3512
3155
|
|
3156
|
+
// Show the hidden image
|
3157
|
+
removeClass(image, CLASS_HIDE);
|
3513
3158
|
this.initPreview();
|
3514
3159
|
this.bind();
|
3515
3160
|
options.initialAspectRatio = Math.max(0, options.initialAspectRatio) || NaN;
|
3516
3161
|
options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;
|
3517
3162
|
options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;
|
3518
3163
|
addClass(cropBox, CLASS_HIDDEN);
|
3519
|
-
|
3520
3164
|
if (!options.guides) {
|
3521
3165
|
addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-dashed")), CLASS_HIDDEN);
|
3522
3166
|
}
|
3523
|
-
|
3524
3167
|
if (!options.center) {
|
3525
3168
|
addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-center")), CLASS_HIDDEN);
|
3526
3169
|
}
|
3527
|
-
|
3528
3170
|
if (options.background) {
|
3529
3171
|
addClass(cropper, "".concat(NAMESPACE, "-bg"));
|
3530
3172
|
}
|
3531
|
-
|
3532
3173
|
if (!options.highlight) {
|
3533
3174
|
addClass(face, CLASS_INVISIBLE);
|
3534
3175
|
}
|
3535
|
-
|
3536
3176
|
if (options.cropBoxMovable) {
|
3537
3177
|
addClass(face, CLASS_MOVE);
|
3538
3178
|
setData(face, DATA_ACTION, ACTION_ALL);
|
3539
3179
|
}
|
3540
|
-
|
3541
3180
|
if (!options.cropBoxResizable) {
|
3542
3181
|
addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-line")), CLASS_HIDDEN);
|
3543
3182
|
addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-point")), CLASS_HIDDEN);
|
3544
3183
|
}
|
3545
|
-
|
3546
3184
|
this.render();
|
3547
3185
|
this.ready = true;
|
3548
3186
|
this.setDragMode(options.dragMode);
|
3549
|
-
|
3550
3187
|
if (options.autoCrop) {
|
3551
3188
|
this.crop();
|
3552
3189
|
}
|
3553
|
-
|
3554
3190
|
this.setData(options.data);
|
3555
|
-
|
3556
3191
|
if (isFunction(options.ready)) {
|
3557
3192
|
addListener(element, EVENT_READY, options.ready, {
|
3558
3193
|
once: true
|
3559
3194
|
});
|
3560
3195
|
}
|
3561
|
-
|
3562
3196
|
dispatchEvent(element, EVENT_READY);
|
3563
3197
|
}
|
3564
3198
|
}, {
|
@@ -3567,11 +3201,13 @@
|
|
3567
3201
|
if (!this.ready) {
|
3568
3202
|
return;
|
3569
3203
|
}
|
3570
|
-
|
3571
3204
|
this.ready = false;
|
3572
3205
|
this.unbind();
|
3573
3206
|
this.resetPreview();
|
3574
|
-
this.cropper.parentNode
|
3207
|
+
var parentNode = this.cropper.parentNode;
|
3208
|
+
if (parentNode) {
|
3209
|
+
parentNode.removeChild(this.cropper);
|
3210
|
+
}
|
3575
3211
|
removeClass(this.element, CLASS_HIDDEN);
|
3576
3212
|
}
|
3577
3213
|
}, {
|
@@ -3592,34 +3228,32 @@
|
|
3592
3228
|
this.stop();
|
3593
3229
|
}
|
3594
3230
|
}
|
3231
|
+
|
3595
3232
|
/**
|
3596
3233
|
* Get the no conflict cropper class.
|
3597
3234
|
* @returns {Cropper} The cropper class.
|
3598
3235
|
*/
|
3599
|
-
|
3600
3236
|
}], [{
|
3601
3237
|
key: "noConflict",
|
3602
3238
|
value: function noConflict() {
|
3603
3239
|
window.Cropper = AnotherCropper;
|
3604
3240
|
return Cropper;
|
3605
3241
|
}
|
3242
|
+
|
3606
3243
|
/**
|
3607
3244
|
* Change the default options.
|
3608
3245
|
* @param {Object} options - The new default options.
|
3609
3246
|
*/
|
3610
|
-
|
3611
3247
|
}, {
|
3612
3248
|
key: "setDefaults",
|
3613
3249
|
value: function setDefaults(options) {
|
3614
3250
|
assign(DEFAULTS, isPlainObject(options) && options);
|
3615
3251
|
}
|
3616
3252
|
}]);
|
3617
|
-
|
3618
3253
|
return Cropper;
|
3619
3254
|
}();
|
3620
|
-
|
3621
3255
|
assign(Cropper.prototype, render, preview, events, handlers, change, methods);
|
3622
3256
|
|
3623
3257
|
return Cropper;
|
3624
3258
|
|
3625
|
-
}))
|
3259
|
+
}));
|