cropper_rails 1.1.4 → 1.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }));