cropper_rails 1.1.4 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,41 +1,54 @@
1
1
  /*!
2
- * Cropper.js v1.5.11
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: 2021-02-17T11:53:27.572Z
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
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
21
- _typeof = function (obj) {
22
- return typeof obj;
23
- };
24
- } else {
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 in Object(iter)) return Array.from(iter);
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'; // Actions
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'; // Classes
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"); // Data keys
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"); // Drag modes
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'; // Events
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'; // Mime types
161
+ var EVENT_ZOOM = 'zoom';
186
162
 
187
- var MIME_TYPE_JPEG = 'image/jpeg'; // RegExps
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; // Misc
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
- /* array-like */
364
- ) {
365
- toArray(data).forEach(function (value, key) {
366
- callback.call(data, value, key, data);
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
- } // IE10-11 doesn't support the second parameter of `classList.toggle`
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
- listeners = _element$listeners === void 0 ? {} : _element$listeners;
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; // Event and CustomEvent on IE9-11 are global objects, not constructors
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
- scaleX = _ref.scaleX,
767
- scaleY = _ref.scaleY,
768
- translateX = _ref.translateX,
769
- translateY = _ref.translateY;
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
- } // Rotate should come first before scale to match orientation transform
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
- pageY = _ref2.pageY;
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
- startY = _ref3.startY;
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
- height = _ref4.height,
882
- width = _ref4.width;
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
- height = _ref5.height,
915
- degree = _ref5.degree;
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
- imageNaturalWidth = _ref6.naturalWidth,
950
- imageNaturalHeight = _ref6.naturalHeight,
951
- _ref6$rotate = _ref6.rotate,
952
- rotate = _ref6$rotate === void 0 ? 0 : _ref6$rotate,
953
- _ref6$scaleX = _ref6.scaleX,
954
- scaleX = _ref6$scaleX === void 0 ? 1 : _ref6$scaleX,
955
- _ref6$scaleY = _ref6.scaleY,
956
- scaleY = _ref6$scaleY === void 0 ? 1 : _ref6$scaleY;
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
- naturalWidth = _ref7.naturalWidth,
959
- naturalHeight = _ref7.naturalHeight;
890
+ naturalWidth = _ref7.naturalWidth,
891
+ naturalHeight = _ref7.naturalHeight;
960
892
  var _ref8$fillColor = _ref8.fillColor,
961
- fillColor = _ref8$fillColor === void 0 ? 'transparent' : _ref8$fillColor,
962
- _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,
963
- imageSmoothingEnabled = _ref8$imageSmoothingE === void 0 ? true : _ref8$imageSmoothingE,
964
- _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,
965
- imageSmoothingQuality = _ref8$imageSmoothingQ === void 0 ? 'low' : _ref8$imageSmoothingQ,
966
- _ref8$maxWidth = _ref8.maxWidth,
967
- maxWidth = _ref8$maxWidth === void 0 ? Infinity : _ref8$maxWidth,
968
- _ref8$maxHeight = _ref8.maxHeight,
969
- maxHeight = _ref8$maxHeight === void 0 ? Infinity : _ref8$maxHeight,
970
- _ref8$minWidth = _ref8.minWidth,
971
- minWidth = _ref8$minWidth === void 0 ? 0 : _ref8$minWidth,
972
- _ref8$minHeight = _ref8.minHeight,
973
- minHeight = _ref8$minHeight === void 0 ? 0 : _ref8$minHeight;
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)); // Note: should always use image's natural sizes for drawing as
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 = []; // Chunk Typed Array for better performance (#435)
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; // Ignores range error when the image does not have correct Exif information
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; // Only handle JPEG image (start by 0xFFD8)
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
- if (littleEndian || endianness === 0x4D4D
1115
- /* bigEndian */
1116
- ) {
1117
- if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
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
- if (dataView.getUint16(_offset, littleEndian) === 0x0112
1139
- /* Orientation */
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
- dataView.setUint16(_offset, 1, littleEndian);
1147
- break;
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
- options = this.options,
1228
- container = this.container,
1229
- cropper = this.cropper;
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
- imageData = this.imageData;
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
- containerData = this.containerData,
1291
- canvasData = this.canvasData,
1292
- cropBoxData = this.cropBoxData;
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
- imageData = this.imageData;
1381
-
1283
+ imageData = this.imageData;
1382
1284
  if (transformed) {
1383
1285
  var _getRotatedSizes = getRotatedSizes({
1384
- width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),
1385
- height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),
1386
- degree: imageData.rotate || 0
1387
- }),
1388
- naturalWidth = _getRotatedSizes.width,
1389
- naturalHeight = _getRotatedSizes.height;
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
- imageData = this.imageData;
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
- canvasData = this.canvasData;
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); // Initialize auto crop area
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); // The width/height of auto crop area must large than "minWidth/Height"
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
- containerData = this.containerData,
1489
- canvasData = this.canvasData,
1490
- cropBoxData = this.cropBoxData,
1491
- limited = this.limited;
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; // The min/maxCropBoxWidth/Height must be less than container's width/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
- } // The minWidth/Height must be less than maxWidth/Height
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
- containerData = this.containerData,
1547
- cropBoxData = this.cropBoxData;
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
- crossOrigin = this.crossOrigin;
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'); // Save the original size for recover
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
- canvasData = this.canvasData,
1664
- cropBoxData = this.cropBoxData;
1542
+ canvasData = this.canvasData,
1543
+ cropBoxData = this.cropBoxData;
1665
1544
  var cropBoxWidth = cropBoxData.width,
1666
- cropBoxHeight = cropBoxData.height;
1545
+ cropBoxHeight = cropBoxData.height;
1667
1546
  var width = imageData.width,
1668
- height = imageData.height;
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
- options = this.options,
1721
- cropper = this.cropper;
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
- options = this.options,
1766
- cropper = this.cropper;
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
- container = this.container,
1818
- containerData = this.containerData;
1819
- var ratio = container.offsetWidth / containerData.width; // Resize when width changed or height changed
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
- if (ratio !== 1 || container.offsetHeight !== containerData.height) {
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
- event.preventDefault(); // Limit wheel speed to prevent zoom too fast (#21)
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
- button = event.button;
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
- if (this.disabled // Handle mouse event and pointer event and ignore touch event
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
- pointers = this.pointers;
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
- } // This line is required for preventing page zooming in iOS browsers
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
- pointers = this.pointers;
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
- canvasData = this.canvasData,
2002
- containerData = this.containerData,
2003
- cropBoxData = this.cropBoxData,
2004
- pointers = this.pointers;
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
- top = cropBoxData.top,
2009
- width = cropBoxData.width,
2010
- height = cropBoxData.height;
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; // Locking aspect ratio in "free mode" by holding shift key
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
- } // Show the crop box if is hidden
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
- } // Override
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); // Render canvas after crop box rendered
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
- left = _this$canvasData.left,
2589
- top = _this$canvasData.top;
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
- canvasData = this.canvasData;
2399
+ canvasData = this.canvasData;
2654
2400
  var width = canvasData.width,
2655
- height = canvasData.height,
2656
- naturalWidth = canvasData.naturalWidth,
2657
- naturalHeight = canvasData.naturalHeight;
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
- }; // Zoom from the triggering point of the event
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
- imageData = this.imageData,
2785
- canvasData = this.canvasData,
2786
- cropBoxData = this.cropBoxData;
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
- imageData = this.imageData,
2840
- canvasData = this.canvasData;
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); // Returns the source canvas if it is not cropped.
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
- initialX = _this$getData.x,
3043
- initialY = _this$getData.y,
3044
- initialWidth = _this$getData.width,
3045
- initialHeight = _this$getData.height;
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
- aspectRatio: aspectRatio,
3070
- width: options.width || (ratio !== 1 ? source.width : initialWidth),
3071
- height: options.height || (ratio !== 1 ? source.height : initialHeight)
3072
- }),
3073
- width = _getAdjustedSizes.width,
3074
- height = _getAdjustedSizes.height;
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
- imageSmoothingEnabled = _options$imageSmoothi === void 0 ? true : _options$imageSmoothi,
3086
- imageSmoothingQuality = options.imageSmoothingQuality;
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
- } // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
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; // Source canvas parameters
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; // Destination canvas parameters
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
- var params = [srcX, srcY, srcWidth, srcHeight]; // Avoid "IndexSizeError"
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
- } // All the numerical parameters should be integer for `drawImage`
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
- dragBox = this.dragBox,
3186
- face = this.face;
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; // e.g.: "img/picture.jpg"
2917
+ this.isImg = true;
3254
2918
 
2919
+ // e.g.: "img/picture.jpg"
3255
2920
  url = element.getAttribute('src') || '';
3256
- this.originalUrl = url; // Stop when it's a blank image
2921
+ this.originalUrl = url;
3257
2922
 
2923
+ // Stop when it's a blank image
3258
2924
  if (!url) {
3259
2925
  return;
3260
- } // e.g.: "https://example.com/img/picture.jpg"
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
- options = this.options;
3283
-
2945
+ options = this.options;
3284
2946
  if (!options.rotatable && !options.scalable) {
3285
2947
  options.checkOrientation = false;
3286
- } // Only IE10+ supports Typed Arrays
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
- } // Detect the mime type of the image directly if it is a Data URL
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
- } // 1. Detect the mime type of the image by a XMLHttpRequest.
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; // 1. Cross origin requests are only supported for protocol schemes:
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
- }; // Bust cache when there is a "crossOrigin" property to avoid browser cache error
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
- } // The third parameter is required for avoiding side-effect (#682)
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
- imageData = this.imageData; // Reset the orientation value to its default value 1
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
- url = this.url;
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
- } // Bust cache when there is not a "crossOrigin" property (#519)
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; // Match all browsers that use WebKit as the layout engine in iOS devices,
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
- }; // Most modern browsers (excepts iOS WebKit)
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
- sizingImage.src = image.src; // iOS WebKit will convert the image automatically
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
- options = this.options,
3486
- image = this.image; // Create cropper elements
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); // Hide the original image
3504
-
3505
- addClass(element, CLASS_HIDDEN); // Inserts the cropper after to the current image
3148
+ canvas.appendChild(image);
3506
3149
 
3507
- container.insertBefore(cropper, element.nextSibling); // Show the image if is hidden
3150
+ // Hide the original image
3151
+ addClass(element, CLASS_HIDDEN);
3508
3152
 
3509
- if (!this.isImg) {
3510
- removeClass(image, CLASS_HIDE);
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.removeChild(this.cropper);
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
+ }));