cropper_rails 1.1.5 → 1.1.6

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