218 lines
4.9 KiB
Plaintext
218 lines
4.9 KiB
Plaintext
Cropper.prototype = {
|
|
constructor: Cropper,
|
|
|
|
init: function () {
|
|
var $this = this.$element;
|
|
var url;
|
|
|
|
if ($this.is('img')) {
|
|
this.isImg = true;
|
|
|
|
// Should use `$.fn.attr` here. e.g.: "img/picture.jpg"
|
|
this.originalUrl = url = $this.attr('src');
|
|
|
|
// Stop when it's a blank image
|
|
if (!url) {
|
|
return;
|
|
}
|
|
|
|
// Should use `$.fn.prop` here. e.g.: "http://example.com/img/picture.jpg"
|
|
url = $this.prop('src');
|
|
} else if ($this.is('canvas') && SUPPORT_CANVAS) {
|
|
url = $this[0].toDataURL();
|
|
}
|
|
|
|
this.load(url);
|
|
},
|
|
|
|
// A shortcut for triggering custom events
|
|
trigger: function (type, data) {
|
|
var e = $.Event(type, data);
|
|
|
|
this.$element.trigger(e);
|
|
|
|
return e;
|
|
},
|
|
|
|
load: function (url) {
|
|
var options = this.options;
|
|
var $this = this.$element;
|
|
var read;
|
|
var xhr;
|
|
|
|
if (!url) {
|
|
return;
|
|
}
|
|
|
|
// Trigger build event first
|
|
$this.one(EVENT_BUILD, options.build);
|
|
|
|
if (this.trigger(EVENT_BUILD).isDefaultPrevented()) {
|
|
return;
|
|
}
|
|
|
|
this.url = url;
|
|
this.image = {};
|
|
|
|
if (!options.checkOrientation || !ArrayBuffer) {
|
|
return this.clone();
|
|
}
|
|
|
|
read = $.proxy(this.read, this);
|
|
|
|
// XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari
|
|
if (REGEXP_DATA_URL.test(url)) {
|
|
return REGEXP_DATA_URL_JPEG.test(url) ?
|
|
read(dataURLToArrayBuffer(url)) :
|
|
this.clone();
|
|
}
|
|
|
|
xhr = new XMLHttpRequest();
|
|
|
|
xhr.onerror = xhr.onabort = $.proxy(function () {
|
|
this.clone();
|
|
}, this);
|
|
|
|
xhr.onload = function () {
|
|
read(this.response);
|
|
};
|
|
|
|
if (options.checkCrossOrigin && isCrossOriginURL(url) && $this.prop('crossOrigin')) {
|
|
url = addTimestamp(url);
|
|
}
|
|
|
|
xhr.open('get', url);
|
|
xhr.responseType = 'arraybuffer';
|
|
xhr.send();
|
|
},
|
|
|
|
read: function (arrayBuffer) {
|
|
var options = this.options;
|
|
var orientation = getOrientation(arrayBuffer);
|
|
var image = this.image;
|
|
var rotate;
|
|
var scaleX;
|
|
var scaleY;
|
|
|
|
if (orientation > 1) {
|
|
this.url = arrayBufferToDataURL(arrayBuffer);
|
|
|
|
switch (orientation) {
|
|
|
|
// flip horizontal
|
|
case 2:
|
|
scaleX = -1;
|
|
break;
|
|
|
|
// rotate left 180°
|
|
case 3:
|
|
rotate = -180;
|
|
break;
|
|
|
|
// flip vertical
|
|
case 4:
|
|
scaleY = -1;
|
|
break;
|
|
|
|
// flip vertical + rotate right 90°
|
|
case 5:
|
|
rotate = 90;
|
|
scaleY = -1;
|
|
break;
|
|
|
|
// rotate right 90°
|
|
case 6:
|
|
rotate = 90;
|
|
break;
|
|
|
|
// flip horizontal + rotate right 90°
|
|
case 7:
|
|
rotate = 90;
|
|
scaleX = -1;
|
|
break;
|
|
|
|
// rotate left 90°
|
|
case 8:
|
|
rotate = -90;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (options.rotatable) {
|
|
image.rotate = rotate;
|
|
}
|
|
|
|
if (options.scalable) {
|
|
image.scaleX = scaleX;
|
|
image.scaleY = scaleY;
|
|
}
|
|
|
|
this.clone();
|
|
},
|
|
|
|
clone: function () {
|
|
var options = this.options;
|
|
var $this = this.$element;
|
|
var url = this.url;
|
|
var crossOrigin = '';
|
|
var crossOriginUrl;
|
|
var $clone;
|
|
|
|
if (options.checkCrossOrigin && isCrossOriginURL(url)) {
|
|
crossOrigin = $this.prop('crossOrigin');
|
|
|
|
if (crossOrigin) {
|
|
crossOriginUrl = url;
|
|
} else {
|
|
crossOrigin = 'anonymous';
|
|
|
|
// Bust cache (#148) when there is not a "crossOrigin" property
|
|
crossOriginUrl = addTimestamp(url);
|
|
}
|
|
}
|
|
|
|
this.crossOrigin = crossOrigin;
|
|
this.crossOriginUrl = crossOriginUrl;
|
|
this.$clone = $clone = $('<img' + getCrossOrigin(crossOrigin) + ' src="' + (crossOriginUrl || url) + '">');
|
|
|
|
if (this.isImg) {
|
|
if ($this[0].complete) {
|
|
this.start();
|
|
} else {
|
|
$this.one(EVENT_LOAD, $.proxy(this.start, this));
|
|
}
|
|
} else {
|
|
$clone.
|
|
one(EVENT_LOAD, $.proxy(this.start, this)).
|
|
one(EVENT_ERROR, $.proxy(this.stop, this)).
|
|
addClass(CLASS_HIDE).
|
|
insertAfter($this);
|
|
}
|
|
},
|
|
|
|
start: function () {
|
|
var $image = this.$element;
|
|
var $clone = this.$clone;
|
|
|
|
if (!this.isImg) {
|
|
$clone.off(EVENT_ERROR, this.stop);
|
|
$image = $clone;
|
|
}
|
|
|
|
getImageSize($image[0], $.proxy(function (naturalWidth, naturalHeight) {
|
|
$.extend(this.image, {
|
|
naturalWidth: naturalWidth,
|
|
naturalHeight: naturalHeight,
|
|
aspectRatio: naturalWidth / naturalHeight
|
|
});
|
|
|
|
this.isLoaded = true;
|
|
this.build();
|
|
}, this));
|
|
},
|
|
|
|
stop: function () {
|
|
this.$clone.remove();
|
|
this.$clone = null;
|
|
},
|