cropper-rails 2.2.1.1 → 2.3.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 18d109addd9bd9f6dfcb09582646d5584694bfba
4
- data.tar.gz: 66b623b517132f47a24cbc479dc3c08314cff729
3
+ metadata.gz: e1ff6df294ba7bba894a943e74ce62cfd9c7f8bb
4
+ data.tar.gz: 3e8f319611b3fc50f2d93f632975907ae3f21670
5
5
  SHA512:
6
- metadata.gz: 01f2bc23e589e3ab86f98df95bae68fca597968d3b9506099bb665f59c95dc7b308b20e52b549c44826aee57f6b5ee7ba3a1c13bb4578c3f5d9b027d3b332c85
7
- data.tar.gz: a9eeb6fc980918288e1b0a9bd3e5a873213f88de6c2fc9f95fb815ad525b252cb0f5f661918d5b57293d19a4f79eb2f9f0382339a736ea7919328b74ca5d123f
6
+ metadata.gz: 3d233dc2dbcd7c7f85f5e76e2f9a45d52d5f62028885eeaebead68397a6ffa678e346f31c2fd61aca89322f430305b5974e52cb8f4de9dedba69be7f662d0c03
7
+ data.tar.gz: 718da9b48066fe2e862b19049ee36174dd61498e0ede12b882bca93b062797cafe91af9c7a5e7814b949dceae7df004daad0ebc52ce019355f68c542378a141d
@@ -1,5 +1,5 @@
1
1
  module Cropper
2
2
  module Rails
3
- VERSION = "2.2.1.1"
3
+ VERSION = "2.3.2.1"
4
4
  end
5
5
  end
@@ -1,11 +1,11 @@
1
1
  /*!
2
- * Cropper v2.2.1
2
+ * Cropper v2.3.2
3
3
  * https://github.com/fengyuanchen/cropper
4
4
  *
5
- * Copyright (c) 2014-2015 Fengyuan Chen and contributors
5
+ * Copyright (c) 2014-2016 Fengyuan Chen and contributors
6
6
  * Released under the MIT license
7
7
  *
8
- * Date: 2015-12-12T07:24:25.791Z
8
+ * Date: 2016-06-08T12:14:46.286Z
9
9
  */
10
10
 
11
11
  (function (factory) {
@@ -27,6 +27,7 @@
27
27
  var $window = $(window);
28
28
  var $document = $(document);
29
29
  var location = window.location;
30
+ var navigator = window.navigator;
30
31
  var ArrayBuffer = window.ArrayBuffer;
31
32
  var Uint8Array = window.Uint8Array;
32
33
  var DataView = window.DataView;
@@ -89,6 +90,7 @@
89
90
 
90
91
  // Supports
91
92
  var SUPPORT_CANVAS = $.isFunction($('<canvas>')[0].getContext);
93
+ var IS_SAFARI_OR_UIWEBVIEW = navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent);
92
94
 
93
95
  // Maths
94
96
  var num = Number;
@@ -101,11 +103,7 @@
101
103
  var round = Math.round;
102
104
  var floor = Math.floor;
103
105
 
104
- // Prototype
105
- var prototype = {
106
- version: '2.2.1'
107
- };
108
-
106
+ // Utilities
109
107
  var fromCharCode = String.fromCharCode;
110
108
 
111
109
  function isNumber(n) {
@@ -159,8 +157,8 @@
159
157
  function getImageSize(image, callback) {
160
158
  var newImage;
161
159
 
162
- // Modern browsers
163
- if (image.naturalWidth) {
160
+ // Modern browsers (ignore Safari, #120 & #509)
161
+ if (image.naturalWidth && !IS_SAFARI_OR_UIWEBVIEW) {
164
162
  return callback(image.naturalWidth, image.naturalHeight);
165
163
  }
166
164
 
@@ -180,14 +178,15 @@
180
178
  var scaleX = options.scaleX;
181
179
  var scaleY = options.scaleY;
182
180
 
183
- if (isNumber(rotate)) {
184
- transforms.push('rotate(' + rotate + 'deg)');
185
- }
186
-
181
+ // Scale should come first before rotate (#633)
187
182
  if (isNumber(scaleX) && isNumber(scaleY)) {
188
183
  transforms.push('scale(' + scaleX + ',' + scaleY + ')');
189
184
  }
190
185
 
186
+ if (isNumber(rotate)) {
187
+ transforms.push('rotate(' + rotate + 'deg)');
188
+ }
189
+
191
190
  return transforms.length ? transforms.join(' ') : 'none';
192
191
  }
193
192
 
@@ -219,61 +218,61 @@
219
218
  function getSourceCanvas(image, data) {
220
219
  var canvas = $('<canvas>')[0];
221
220
  var context = canvas.getContext('2d');
222
- var x = 0;
223
- var y = 0;
224
- var width = data.naturalWidth;
225
- var height = data.naturalHeight;
221
+ var dstX = 0;
222
+ var dstY = 0;
223
+ var dstWidth = data.naturalWidth;
224
+ var dstHeight = data.naturalHeight;
226
225
  var rotate = data.rotate;
227
226
  var scaleX = data.scaleX;
228
227
  var scaleY = data.scaleY;
229
228
  var scalable = isNumber(scaleX) && isNumber(scaleY) && (scaleX !== 1 || scaleY !== 1);
230
229
  var rotatable = isNumber(rotate) && rotate !== 0;
231
230
  var advanced = rotatable || scalable;
232
- var canvasWidth = width;
233
- var canvasHeight = height;
231
+ var canvasWidth = dstWidth * abs(scaleX || 1);
232
+ var canvasHeight = dstHeight * abs(scaleY || 1);
234
233
  var translateX;
235
234
  var translateY;
236
235
  var rotated;
237
236
 
238
237
  if (scalable) {
239
- translateX = width / 2;
240
- translateY = height / 2;
238
+ translateX = canvasWidth / 2;
239
+ translateY = canvasHeight / 2;
241
240
  }
242
241
 
243
242
  if (rotatable) {
244
243
  rotated = getRotatedSizes({
245
- width: width,
246
- height: height,
244
+ width: canvasWidth,
245
+ height: canvasHeight,
247
246
  degree: rotate
248
247
  });
249
248
 
250
249
  canvasWidth = rotated.width;
251
250
  canvasHeight = rotated.height;
252
- translateX = rotated.width / 2;
253
- translateY = rotated.height / 2;
251
+ translateX = canvasWidth / 2;
252
+ translateY = canvasHeight / 2;
254
253
  }
255
254
 
256
255
  canvas.width = canvasWidth;
257
256
  canvas.height = canvasHeight;
258
257
 
259
258
  if (advanced) {
260
- x = -width / 2;
261
- y = -height / 2;
259
+ dstX = -dstWidth / 2;
260
+ dstY = -dstHeight / 2;
262
261
 
263
262
  context.save();
264
263
  context.translate(translateX, translateY);
265
264
  }
266
265
 
267
- if (rotatable) {
268
- context.rotate(rotate * Math.PI / 180);
269
- }
270
-
271
- // Should call `scale` after rotated
266
+ // Scale should come first before rotate (#633, #709)
272
267
  if (scalable) {
273
268
  context.scale(scaleX, scaleY);
274
269
  }
275
270
 
276
- context.drawImage(image, floor(x), floor(y), floor(width), floor(height));
271
+ if (rotatable) {
272
+ context.rotate(rotate * Math.PI / 180);
273
+ }
274
+
275
+ context.drawImage(image, floor(dstX), floor(dstY), floor(dstWidth), floor(dstHeight));
277
276
 
278
277
  if (advanced) {
279
278
  context.restore();
@@ -282,6 +281,27 @@
282
281
  return canvas;
283
282
  }
284
283
 
284
+ function getTouchesCenter(touches) {
285
+ var length = touches.length;
286
+ var pageX = 0;
287
+ var pageY = 0;
288
+
289
+ if (length) {
290
+ $.each(touches, function (i, touch) {
291
+ pageX += touch.pageX;
292
+ pageY += touch.pageY;
293
+ });
294
+
295
+ pageX /= length;
296
+ pageY /= length;
297
+ }
298
+
299
+ return {
300
+ pageX: pageX,
301
+ pageY: pageY
302
+ };
303
+ }
304
+
285
305
  function getStringFromCharCode(dataView, start, length) {
286
306
  var str = '';
287
307
  var i;
@@ -355,8 +375,11 @@
355
375
  // Get the original orientation value
356
376
  orientation = dataView.getUint16(offset, littleEndian);
357
377
 
358
- // Override the orientation with the default value: 1
359
- dataView.setUint16(offset, 1, littleEndian);
378
+ // Override the orientation with its default value for Safari (#120)
379
+ if (IS_SAFARI_OR_UIWEBVIEW) {
380
+ dataView.setUint16(offset, 1, littleEndian);
381
+ }
382
+
360
383
  break;
361
384
  }
362
385
  }
@@ -405,6 +428,7 @@
405
428
  this.isDisabled = false;
406
429
  this.isReplaced = false;
407
430
  this.isLimited = false;
431
+ this.wheeling = false;
408
432
  this.isImg = false;
409
433
  this.originalUrl = '';
410
434
  this.canvas = null;
@@ -412,7 +436,9 @@
412
436
  this.init();
413
437
  }
414
438
 
415
- $.extend(prototype, {
439
+ Cropper.prototype = {
440
+ constructor: Cropper,
441
+
416
442
  init: function () {
417
443
  var $this = this.$element;
418
444
  var url;
@@ -489,6 +515,10 @@
489
515
  read(this.response);
490
516
  };
491
517
 
518
+ if (options.checkCrossOrigin && isCrossOriginURL(url) && $this.prop('crossOrigin')) {
519
+ url = addTimestamp(url);
520
+ }
521
+
492
522
  xhr.open('get', url);
493
523
  xhr.responseType = 'arraybuffer';
494
524
  xhr.send();
@@ -569,9 +599,12 @@
569
599
  if (options.checkCrossOrigin && isCrossOriginURL(url)) {
570
600
  crossOrigin = $this.prop('crossOrigin');
571
601
 
572
- // Bust cache (#148), only when there was not a "crossOrigin" property
573
- if (!crossOrigin) {
602
+ if (crossOrigin) {
603
+ crossOriginUrl = url;
604
+ } else {
574
605
  crossOrigin = 'anonymous';
606
+
607
+ // Bust cache (#148) when there is not a "crossOrigin" property
575
608
  crossOriginUrl = addTimestamp(url);
576
609
  }
577
610
  }
@@ -619,10 +652,8 @@
619
652
  stop: function () {
620
653
  this.$clone.remove();
621
654
  this.$clone = null;
622
- }
623
- });
655
+ },
624
656
 
625
- $.extend(prototype, {
626
657
  build: function () {
627
658
  var options = this.options;
628
659
  var $this = this.$element;
@@ -706,6 +737,7 @@
706
737
  // Trigger the built event asynchronously to keep `data('cropper')` is defined
707
738
  setTimeout($.proxy(function () {
708
739
  this.trigger(EVENT_BUILT);
740
+ this.trigger(EVENT_CROP, this.getData());
709
741
  this.isCompleted = true;
710
742
  }, this), 0);
711
743
  },
@@ -740,10 +772,8 @@
740
772
 
741
773
  this.$cropper.remove();
742
774
  this.$cropper = null;
743
- }
744
- });
775
+ },
745
776
 
746
- $.extend(prototype, {
747
777
  render: function () {
748
778
  this.initContainer();
749
779
  this.initCanvas();
@@ -1202,23 +1232,17 @@
1202
1232
 
1203
1233
  if (this.isCompleted) {
1204
1234
  this.trigger(EVENT_CROP, this.getData());
1205
- } else if (!this.isBuilt) {
1206
-
1207
- // Only trigger one crop event before complete
1208
- this.$element.one(EVENT_BUILT, $.proxy(function () {
1209
- this.trigger(EVENT_CROP, this.getData());
1210
- }, this));
1211
1235
  }
1212
- }
1213
- });
1236
+ },
1214
1237
 
1215
- $.extend(prototype, {
1216
1238
  initPreview: function () {
1217
1239
  var crossOrigin = getCrossOrigin(this.crossOrigin);
1218
1240
  var url = crossOrigin ? this.crossOriginUrl : this.url;
1241
+ var $clone2;
1219
1242
 
1220
1243
  this.$preview = $(this.options.preview);
1221
- this.$viewBox.html('<img' + crossOrigin + ' src="' + url + '">');
1244
+ this.$clone2 = $clone2 = $('<img' + crossOrigin + ' src="' + url + '">');
1245
+ this.$viewBox.html($clone2);
1222
1246
  this.$preview.each(function () {
1223
1247
  var $this = $(this);
1224
1248
 
@@ -1271,7 +1295,7 @@
1271
1295
  return;
1272
1296
  }
1273
1297
 
1274
- this.$viewBox.find('img').css({
1298
+ this.$clone2.css({
1275
1299
  width: width,
1276
1300
  height: height,
1277
1301
  marginLeft: -left,
@@ -1310,10 +1334,8 @@
1310
1334
  transform: getTransform(image)
1311
1335
  });
1312
1336
  });
1313
- }
1314
- });
1337
+ },
1315
1338
 
1316
- $.extend(prototype, {
1317
1339
  bind: function () {
1318
1340
  var options = this.options;
1319
1341
  var $this = this.$element;
@@ -1400,10 +1422,8 @@
1400
1422
  if (options.responsive) {
1401
1423
  $window.off(EVENT_RESIZE, this._resize);
1402
1424
  }
1403
- }
1404
- });
1425
+ },
1405
1426
 
1406
- $.extend(prototype, {
1407
1427
  resize: function () {
1408
1428
  var restore = this.options.restore;
1409
1429
  var $container = this.$container;
@@ -1452,8 +1472,7 @@
1452
1472
  },
1453
1473
 
1454
1474
  wheel: function (event) {
1455
- var originalEvent = event.originalEvent;
1456
- var e = originalEvent || event;
1475
+ var e = event.originalEvent || event;
1457
1476
  var ratio = num(this.options.wheelZoomRatio) || 0.1;
1458
1477
  var delta = 1;
1459
1478
 
@@ -1463,6 +1482,17 @@
1463
1482
 
1464
1483
  event.preventDefault();
1465
1484
 
1485
+ // Limit wheel speed to prevent zoom too fast
1486
+ if (this.wheeling) {
1487
+ return;
1488
+ }
1489
+
1490
+ this.wheeling = true;
1491
+
1492
+ setTimeout($.proxy(function () {
1493
+ this.wheeling = false;
1494
+ }, this), 50);
1495
+
1466
1496
  if (e.deltaY) {
1467
1497
  delta = e.deltaY > 0 ? 1 : -1;
1468
1498
  } else if (e.wheelDelta) {
@@ -1471,7 +1501,7 @@
1471
1501
  delta = e.detail > 0 ? 1 : -1;
1472
1502
  }
1473
1503
 
1474
- this.zoom(-delta * ratio, originalEvent);
1504
+ this.zoom(-delta * ratio, event);
1475
1505
  },
1476
1506
 
1477
1507
  cropStart: function (event) {
@@ -1571,7 +1601,7 @@
1571
1601
  this.endX = e.pageX || originalEvent && originalEvent.pageX;
1572
1602
  this.endY = e.pageY || originalEvent && originalEvent.pageY;
1573
1603
 
1574
- this.change(e.shiftKey, action === ACTION_ZOOM ? originalEvent : null);
1604
+ this.change(e.shiftKey, action === ACTION_ZOOM ? event : null);
1575
1605
  }
1576
1606
  },
1577
1607
 
@@ -1598,11 +1628,9 @@
1598
1628
  action: action
1599
1629
  });
1600
1630
  }
1601
- }
1602
- });
1631
+ },
1603
1632
 
1604
- $.extend(prototype, {
1605
- change: function (shiftKey, originalEvent) {
1633
+ change: function (shiftKey, event) {
1606
1634
  var options = this.options;
1607
1635
  var aspectRatio = options.aspectRatio;
1608
1636
  var action = this.action;
@@ -1628,11 +1656,11 @@
1628
1656
  aspectRatio = width && height ? width / height : 1;
1629
1657
  }
1630
1658
 
1631
- if (this.limited) {
1659
+ if (this.isLimited) {
1632
1660
  minLeft = cropBox.minLeft;
1633
1661
  minTop = cropBox.minTop;
1634
- maxWidth = minLeft + min(container.width, canvas.width);
1635
- maxHeight = minTop + min(container.height, canvas.height);
1662
+ maxWidth = minLeft + min(container.width, canvas.left + canvas.width);
1663
+ maxHeight = minTop + min(container.height, canvas.top + canvas.height);
1636
1664
  }
1637
1665
 
1638
1666
  range = {
@@ -1945,7 +1973,7 @@
1945
1973
  abs(this.startY - this.startY2),
1946
1974
  abs(this.endX - this.endX2),
1947
1975
  abs(this.endY - this.endY2)
1948
- ), originalEvent);
1976
+ ), event);
1949
1977
  this.startX2 = this.endX2;
1950
1978
  this.startY2 = this.endY2;
1951
1979
  renderable = false;
@@ -1980,7 +2008,7 @@
1980
2008
  this.$cropBox.removeClass(CLASS_HIDDEN);
1981
2009
  this.isCropped = true;
1982
2010
 
1983
- if (this.limited) {
2011
+ if (this.isLimited) {
1984
2012
  this.limitCropBox(true, true);
1985
2013
  }
1986
2014
  }
@@ -2003,10 +2031,7 @@
2003
2031
  // Override
2004
2032
  this.startX = this.endX;
2005
2033
  this.startY = this.endY;
2006
- }
2007
- });
2008
-
2009
- $.extend(prototype, {
2034
+ },
2010
2035
 
2011
2036
  // Show the crop box manually
2012
2037
  crop: function () {
@@ -2074,17 +2099,30 @@
2074
2099
  * Replace the image's src and rebuild the cropper
2075
2100
  *
2076
2101
  * @param {String} url
2102
+ * @param {Boolean} onlyColorChanged (optional)
2077
2103
  */
2078
- replace: function (url) {
2104
+ replace: function (url, onlyColorChanged) {
2079
2105
  if (!this.isDisabled && url) {
2080
2106
  if (this.isImg) {
2081
- this.isReplaced = true;
2082
2107
  this.$element.attr('src', url);
2083
2108
  }
2084
2109
 
2085
- // Clear previous data
2086
- this.options.data = null;
2087
- this.load(url);
2110
+ if (onlyColorChanged) {
2111
+ this.url = url;
2112
+ this.$clone.attr('src', url);
2113
+
2114
+ if (this.isBuilt) {
2115
+ this.$preview.find('img').add(this.$clone2).attr('src', url);
2116
+ }
2117
+ } else {
2118
+ if (this.isImg) {
2119
+ this.isReplaced = true;
2120
+ }
2121
+
2122
+ // Clear previous data
2123
+ this.options.data = null;
2124
+ this.load(url);
2125
+ }
2088
2126
  }
2089
2127
  },
2090
2128
 
@@ -2180,9 +2218,9 @@
2180
2218
  * Zoom the canvas with a relative ratio
2181
2219
  *
2182
2220
  * @param {Number} ratio
2183
- * @param {Event} _originalEvent (private)
2221
+ * @param {jQuery Event} _event (private)
2184
2222
  */
2185
- zoom: function (ratio, _originalEvent) {
2223
+ zoom: function (ratio, _event) {
2186
2224
  var canvas = this.canvas;
2187
2225
 
2188
2226
  ratio = num(ratio);
@@ -2193,24 +2231,27 @@
2193
2231
  ratio = 1 + ratio;
2194
2232
  }
2195
2233
 
2196
- this.zoomTo(canvas.width * ratio / canvas.naturalWidth, _originalEvent);
2234
+ this.zoomTo(canvas.width * ratio / canvas.naturalWidth, _event);
2197
2235
  },
2198
2236
 
2199
2237
  /**
2200
2238
  * Zoom the canvas to an absolute ratio
2201
2239
  *
2202
2240
  * @param {Number} ratio
2203
- * @param {Event} _originalEvent (private)
2241
+ * @param {jQuery Event} _event (private)
2204
2242
  */
2205
- zoomTo: function (ratio, _originalEvent) {
2243
+ zoomTo: function (ratio, _event) {
2206
2244
  var options = this.options;
2207
2245
  var canvas = this.canvas;
2208
2246
  var width = canvas.width;
2209
2247
  var height = canvas.height;
2210
2248
  var naturalWidth = canvas.naturalWidth;
2211
2249
  var naturalHeight = canvas.naturalHeight;
2250
+ var originalEvent;
2212
2251
  var newWidth;
2213
2252
  var newHeight;
2253
+ var offset;
2254
+ var center;
2214
2255
 
2215
2256
  ratio = num(ratio);
2216
2257
 
@@ -2218,16 +2259,39 @@
2218
2259
  newWidth = naturalWidth * ratio;
2219
2260
  newHeight = naturalHeight * ratio;
2220
2261
 
2262
+ if (_event) {
2263
+ originalEvent = _event.originalEvent;
2264
+ }
2265
+
2221
2266
  if (this.trigger(EVENT_ZOOM, {
2222
- originalEvent: _originalEvent,
2267
+ originalEvent: originalEvent,
2223
2268
  oldRatio: width / naturalWidth,
2224
2269
  ratio: newWidth / naturalWidth
2225
2270
  }).isDefaultPrevented()) {
2226
2271
  return;
2227
2272
  }
2228
2273
 
2229
- canvas.left -= (newWidth - width) / 2;
2230
- canvas.top -= (newHeight - height) / 2;
2274
+ if (originalEvent) {
2275
+ offset = this.$cropper.offset();
2276
+ center = originalEvent.touches ? getTouchesCenter(originalEvent.touches) : {
2277
+ pageX: _event.pageX || originalEvent.pageX || 0,
2278
+ pageY: _event.pageY || originalEvent.pageY || 0
2279
+ };
2280
+
2281
+ // Zoom from the triggering point of the event
2282
+ canvas.left -= (newWidth - width) * (
2283
+ ((center.pageX - offset.left) - canvas.left) / width
2284
+ );
2285
+ canvas.top -= (newHeight - height) * (
2286
+ ((center.pageY - offset.top) - canvas.top) / height
2287
+ );
2288
+ } else {
2289
+
2290
+ // Zoom from the center of the canvas
2291
+ canvas.left -= (newWidth - width) / 2;
2292
+ canvas.top -= (newHeight - height) / 2;
2293
+ }
2294
+
2231
2295
  canvas.width = newWidth;
2232
2296
  canvas.height = newHeight;
2233
2297
  this.renderCanvas(true);
@@ -2556,12 +2620,12 @@
2556
2620
  cropBox.top = data.top;
2557
2621
  }
2558
2622
 
2559
- if (isNumber(data.width) && data.width !== cropBox.width) {
2623
+ if (isNumber(data.width)) {
2560
2624
  isWidthChanged = true;
2561
2625
  cropBox.width = data.width;
2562
2626
  }
2563
2627
 
2564
- if (isNumber(data.height) && data.height !== cropBox.height) {
2628
+ if (isNumber(data.height)) {
2565
2629
  isHeightChanged = true;
2566
2630
  cropBox.height = data.height;
2567
2631
  }
@@ -2597,10 +2661,14 @@
2597
2661
  var context;
2598
2662
  var data;
2599
2663
 
2600
- if (!this.isBuilt || !this.isCropped || !SUPPORT_CANVAS) {
2664
+ if (!this.isBuilt || !SUPPORT_CANVAS) {
2601
2665
  return;
2602
2666
  }
2603
2667
 
2668
+ if (!this.isCropped) {
2669
+ return getSourceCanvas(this.$clone[0], this.image);
2670
+ }
2671
+
2604
2672
  if (!$.isPlainObject(options)) {
2605
2673
  options = {};
2606
2674
  }
@@ -2623,9 +2691,9 @@
2623
2691
  }
2624
2692
  }
2625
2693
 
2626
-
2627
- canvasWidth = round(scaledWidth || originalWidth);
2628
- canvasHeight = round(scaledHeight || originalHeight);
2694
+ // The canvas element will use `Math.floor` on a float number, so floor first
2695
+ canvasWidth = floor(scaledWidth || originalWidth);
2696
+ canvasHeight = floor(scaledHeight || originalHeight);
2629
2697
 
2630
2698
  canvas = $('<canvas>')[0];
2631
2699
  canvas.width = canvasWidth;
@@ -2642,11 +2710,12 @@
2642
2710
  var source = getSourceCanvas(this.$clone[0], this.image);
2643
2711
  var sourceWidth = source.width;
2644
2712
  var sourceHeight = source.height;
2645
- var args = [source];
2713
+ var canvas = this.canvas;
2714
+ var params = [source];
2646
2715
 
2647
2716
  // Source canvas
2648
- var srcX = data.x;
2649
- var srcY = data.y;
2717
+ var srcX = data.x + canvas.naturalWidth * (abs(data.scaleX || 1) - 1) / 2;
2718
+ var srcY = data.y + canvas.naturalHeight * (abs(data.scaleY || 1) - 1) / 2;
2650
2719
  var srcWidth;
2651
2720
  var srcHeight;
2652
2721
 
@@ -2679,7 +2748,7 @@
2679
2748
  }
2680
2749
 
2681
2750
  // All the numerical parameters should be integer for `drawImage` (#476)
2682
- args.push(floor(srcX), floor(srcY), floor(srcWidth), floor(srcHeight));
2751
+ params.push(floor(srcX), floor(srcY), floor(srcWidth), floor(srcHeight));
2683
2752
 
2684
2753
  // Scale destination sizes
2685
2754
  if (scaledRatio) {
@@ -2691,10 +2760,10 @@
2691
2760
 
2692
2761
  // Avoid "IndexSizeError" in IE and Firefox
2693
2762
  if (dstWidth > 0 && dstHeight > 0) {
2694
- args.push(floor(dstX), floor(dstY), floor(dstWidth), floor(dstHeight));
2763
+ params.push(floor(dstX), floor(dstY), floor(dstWidth), floor(dstHeight));
2695
2764
  }
2696
2765
 
2697
- return args;
2766
+ return params;
2698
2767
  }).call(this));
2699
2768
 
2700
2769
  return canvas;
@@ -2753,9 +2822,7 @@
2753
2822
  }
2754
2823
  }
2755
2824
  }
2756
- });
2757
-
2758
- $.extend(Cropper.prototype, prototype);
2825
+ };
2759
2826
 
2760
2827
  Cropper.DEFAULTS = {
2761
2828
 
@@ -2891,24 +2958,26 @@
2891
2958
  Cropper.other = $.fn.cropper;
2892
2959
 
2893
2960
  // Register as jQuery plugin
2894
- $.fn.cropper = function (options) {
2961
+ $.fn.cropper = function (option) {
2895
2962
  var args = toArray(arguments, 1);
2896
2963
  var result;
2897
2964
 
2898
2965
  this.each(function () {
2899
2966
  var $this = $(this);
2900
2967
  var data = $this.data(NAMESPACE);
2968
+ var options;
2901
2969
  var fn;
2902
2970
 
2903
2971
  if (!data) {
2904
- if (/destroy/.test(options)) {
2972
+ if (/destroy/.test(option)) {
2905
2973
  return;
2906
2974
  }
2907
2975
 
2976
+ options = $.extend({}, $this.data(), $.isPlainObject(option) && option);
2908
2977
  $this.data(NAMESPACE, (data = new Cropper(this, options)));
2909
2978
  }
2910
2979
 
2911
- if (typeof options === 'string' && $.isFunction(fn = data[options])) {
2980
+ if (typeof option === 'string' && $.isFunction(fn = data[option])) {
2912
2981
  result = fn.apply(data, args);
2913
2982
  }
2914
2983
  });
@@ -1,36 +1,41 @@
1
1
  /*!
2
- * Cropper v2.2.1
2
+ * Cropper v2.3.2
3
3
  * https://github.com/fengyuanchen/cropper
4
4
  *
5
- * Copyright (c) 2014-2015 Fengyuan Chen and contributors
5
+ * Copyright (c) 2014-2016 Fengyuan Chen and contributors
6
6
  * Released under the MIT license
7
7
  *
8
- * Date: 2015-12-12T07:24:22.254Z
8
+ * Date: 2016-06-08T12:14:46.286Z
9
9
  */
10
10
  .cropper-container {
11
- position: relative;
12
11
  font-size: 0;
13
12
  line-height: 0;
14
- direction: ltr !important;
15
- -ms-touch-action: none;
16
- touch-action: none;
13
+
14
+ position: relative;
15
+
17
16
  -webkit-user-select: none;
18
17
  -moz-user-select: none;
19
18
  -ms-user-select: none;
20
19
  user-select: none;
20
+
21
+ direction: ltr !important;
22
+ -ms-touch-action: none;
23
+ touch-action: none;
21
24
  -webkit-tap-highlight-color: transparent;
22
25
  -webkit-touch-callout: none;
23
26
  }
24
27
 
25
28
  .cropper-container img {
26
29
  display: block;
27
- image-orientation: 0deg !important;
30
+
31
+ width: 100%;
28
32
  min-width: 0 !important;
29
- min-height: 0 !important;
30
33
  max-width: none !important;
31
- max-height: none !important;
32
- width: 100%;
33
34
  height: 100%;
35
+ min-height: 0 !important;
36
+ max-height: none !important;
37
+
38
+ image-orientation: 0deg !important;
34
39
  }
35
40
 
36
41
  .cropper-wrap-box,
@@ -50,73 +55,93 @@
50
55
  }
51
56
 
52
57
  .cropper-drag-box {
53
- background-color: #fff;
54
58
  opacity: 0;
59
+ background-color: #fff;
60
+
55
61
  filter: alpha(opacity=0);
56
62
  }
57
63
 
58
64
  .cropper-modal {
65
+ opacity: .5;
59
66
  background-color: #000;
60
- opacity: 0.5;
67
+
61
68
  filter: alpha(opacity=50);
62
69
  }
63
70
 
64
71
  .cropper-view-box {
65
72
  display: block;
66
73
  overflow: hidden;
67
- outline: 1px solid #39f;
68
- outline-color: rgba(51, 153, 255, 0.75);
74
+
69
75
  width: 100%;
70
76
  height: 100%;
77
+
78
+ outline: 1px solid #39f;
79
+ outline-color: rgba(51, 153, 255, .75);
71
80
  }
72
81
 
73
82
  .cropper-dashed {
74
83
  position: absolute;
84
+
75
85
  display: block;
86
+
87
+ opacity: .5;
76
88
  border: 0 dashed #eee;
77
- opacity: 0.5;
89
+
78
90
  filter: alpha(opacity=50);
79
91
  }
80
92
 
81
93
  .cropper-dashed.dashed-h {
82
94
  top: 33.33333%;
83
95
  left: 0;
84
- border-top-width: 1px;
85
- border-bottom-width: 1px;
96
+
86
97
  width: 100%;
87
98
  height: 33.33333%;
99
+
100
+ border-top-width: 1px;
101
+ border-bottom-width: 1px;
88
102
  }
89
103
 
90
104
  .cropper-dashed.dashed-v {
91
105
  top: 0;
92
106
  left: 33.33333%;
93
- border-right-width: 1px;
94
- border-left-width: 1px;
107
+
95
108
  width: 33.33333%;
96
109
  height: 100%;
110
+
111
+ border-right-width: 1px;
112
+ border-left-width: 1px;
97
113
  }
98
114
 
99
115
  .cropper-center {
100
116
  position: absolute;
101
117
  top: 50%;
102
118
  left: 50%;
119
+
103
120
  display: block;
121
+
104
122
  width: 0;
105
123
  height: 0;
106
- opacity: 0.75;
124
+
125
+ opacity: .75;
126
+
107
127
  filter: alpha(opacity=75);
108
128
  }
109
129
 
110
- .cropper-center:before, .cropper-center:after {
130
+ .cropper-center:before,
131
+ .cropper-center:after {
111
132
  position: absolute;
133
+
112
134
  display: block;
135
+
136
+ content: ' ';
137
+
113
138
  background-color: #eee;
114
- content: " ";
115
139
  }
116
140
 
117
141
  .cropper-center:before {
118
142
  top: 0;
119
143
  left: -3px;
144
+
120
145
  width: 7px;
121
146
  height: 1px;
122
147
  }
@@ -124,6 +149,7 @@
124
149
  .cropper-center:after {
125
150
  top: -3px;
126
151
  left: 0;
152
+
127
153
  width: 1px;
128
154
  height: 7px;
129
155
  }
@@ -132,16 +158,21 @@
132
158
  .cropper-line,
133
159
  .cropper-point {
134
160
  position: absolute;
161
+
135
162
  display: block;
163
+
136
164
  width: 100%;
137
165
  height: 100%;
138
- opacity: 0.1;
166
+
167
+ opacity: .1;
168
+
139
169
  filter: alpha(opacity=10);
140
170
  }
141
171
 
142
172
  .cropper-face {
143
173
  top: 0;
144
174
  left: 0;
175
+
145
176
  background-color: #fff;
146
177
  }
147
178
 
@@ -152,92 +183,117 @@
152
183
  .cropper-line.line-e {
153
184
  top: 0;
154
185
  right: -3px;
186
+
155
187
  width: 5px;
188
+
156
189
  cursor: e-resize;
157
190
  }
158
191
 
159
192
  .cropper-line.line-n {
160
193
  top: -3px;
161
194
  left: 0;
195
+
162
196
  height: 5px;
197
+
163
198
  cursor: n-resize;
164
199
  }
165
200
 
166
201
  .cropper-line.line-w {
167
202
  top: 0;
168
203
  left: -3px;
204
+
169
205
  width: 5px;
206
+
170
207
  cursor: w-resize;
171
208
  }
172
209
 
173
210
  .cropper-line.line-s {
174
211
  bottom: -3px;
175
212
  left: 0;
213
+
176
214
  height: 5px;
215
+
177
216
  cursor: s-resize;
178
217
  }
179
218
 
180
219
  .cropper-point {
181
- background-color: #39f;
182
220
  width: 5px;
183
221
  height: 5px;
184
- opacity: 0.75;
222
+
223
+ opacity: .75;
224
+ background-color: #39f;
225
+
185
226
  filter: alpha(opacity=75);
186
227
  }
187
228
 
188
229
  .cropper-point.point-e {
189
230
  top: 50%;
190
231
  right: -3px;
232
+
191
233
  margin-top: -3px;
234
+
192
235
  cursor: e-resize;
193
236
  }
194
237
 
195
238
  .cropper-point.point-n {
196
239
  top: -3px;
197
240
  left: 50%;
241
+
198
242
  margin-left: -3px;
243
+
199
244
  cursor: n-resize;
200
245
  }
201
246
 
202
247
  .cropper-point.point-w {
203
248
  top: 50%;
204
249
  left: -3px;
250
+
205
251
  margin-top: -3px;
252
+
206
253
  cursor: w-resize;
207
254
  }
208
255
 
209
256
  .cropper-point.point-s {
210
257
  bottom: -3px;
211
258
  left: 50%;
259
+
212
260
  margin-left: -3px;
261
+
213
262
  cursor: s-resize;
214
263
  }
215
264
 
216
265
  .cropper-point.point-ne {
217
266
  top: -3px;
218
267
  right: -3px;
268
+
219
269
  cursor: ne-resize;
220
270
  }
221
271
 
222
272
  .cropper-point.point-nw {
223
273
  top: -3px;
224
274
  left: -3px;
275
+
225
276
  cursor: nw-resize;
226
277
  }
227
278
 
228
279
  .cropper-point.point-sw {
229
280
  bottom: -3px;
230
281
  left: -3px;
282
+
231
283
  cursor: sw-resize;
232
284
  }
233
285
 
234
286
  .cropper-point.point-se {
235
287
  right: -3px;
236
288
  bottom: -3px;
237
- cursor: se-resize;
289
+
238
290
  width: 20px;
239
291
  height: 20px;
292
+
293
+ cursor: se-resize;
294
+
240
295
  opacity: 1;
296
+
241
297
  filter: alpha(opacity=100);
242
298
  }
243
299
 
@@ -245,12 +301,17 @@
245
301
  position: absolute;
246
302
  right: -50%;
247
303
  bottom: -50%;
304
+
248
305
  display: block;
249
- content: " ";
250
- background-color: #39f;
306
+
251
307
  width: 200%;
252
308
  height: 200%;
309
+
310
+ content: ' ';
311
+
253
312
  opacity: 0;
313
+ background-color: #39f;
314
+
254
315
  filter: alpha(opacity=0);
255
316
  }
256
317
 
@@ -272,23 +333,28 @@
272
333
  .cropper-point.point-se {
273
334
  width: 5px;
274
335
  height: 5px;
275
- opacity: 0.75;
336
+
337
+ opacity: .75;
338
+
276
339
  filter: alpha(opacity=75);
277
340
  }
278
341
  }
279
342
 
280
343
  .cropper-invisible {
281
344
  opacity: 0;
345
+
282
346
  filter: alpha(opacity=0);
283
347
  }
284
348
 
285
349
  .cropper-bg {
286
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC");
350
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
287
351
  }
288
352
 
289
353
  .cropper-hide {
290
354
  position: absolute;
355
+
291
356
  display: block;
357
+
292
358
  width: 0;
293
359
  height: 0;
294
360
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cropper-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1.1
4
+ version: 2.3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cristian Bica
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-12-15 00:00:00.000000000 Z
11
+ date: 2016-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -97,3 +97,4 @@ signing_key:
97
97
  specification_version: 4
98
98
  summary: Fengyuanchen's Cropper with Rails assets pipeline.
99
99
  test_files: []
100
+ has_rdoc: