/home/mip/mip/public/template/AdminLTE/plugins/cropper-master/src/js/cropper.js
import $ from 'jquery';
import DEFAULTS from './defaults';
import TEMPLATE from './template';
import render from './render';
import preview from './preview';
import events from './events';
import handlers from './handlers';
import change from './change';
import methods from './methods';
import * as utils from './utilities';
const CLASS_HIDDEN = 'cropper-hidden';
const REGEXP_DATA_URL = /^data:/;
const REGEXP_DATA_URL_JPEG = /^data:image\/jpeg.*;base64,/;
class Cropper {
constructor(element, options) {
const self = this;
self.$element = $(element);
self.options = $.extend({}, DEFAULTS, $.isPlainObject(options) && options);
self.loaded = false;
self.ready = false;
self.completed = false;
self.rotated = false;
self.cropped = false;
self.disabled = false;
self.replaced = false;
self.limited = false;
self.wheeling = false;
self.isImg = false;
self.originalUrl = '';
self.canvas = null;
self.cropBox = null;
self.pointers = {};
self.init();
}
init() {
const self = this;
const $this = self.$element;
let url;
if ($this.is('img')) {
self.isImg = true;
// Should use `$.fn.attr` here. e.g.: "img/picture.jpg"
self.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') && window.HTMLCanvasElement) {
url = $this[0].toDataURL();
}
self.load(url);
}
// A shortcut for triggering custom events
trigger(type, data) {
const e = $.Event(type, data);
this.$element.trigger(e);
return e;
}
load(url) {
const self = this;
const options = self.options;
const $this = self.$element;
if (!url) {
return;
}
self.url = url;
self.image = {};
if (!options.checkOrientation || !ArrayBuffer) {
self.clone();
return;
}
// XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari
if (REGEXP_DATA_URL.test(url)) {
if (REGEXP_DATA_URL_JPEG.test(url)) {
self.read(utils.dataURLToArrayBuffer(url));
} else {
self.clone();
}
return;
}
const xhr = new XMLHttpRequest();
xhr.onerror = xhr.onabort = $.proxy(() => {
self.clone();
}, this);
xhr.onload = function load() {
self.read(this.response);
};
if (options.checkCrossOrigin && utils.isCrossOriginURL(url) && $this.prop('crossOrigin')) {
url = utils.addTimestamp(url);
}
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.send();
}
read(arrayBuffer) {
const self = this;
const options = self.options;
const orientation = utils.getOrientation(arrayBuffer);
const image = self.image;
let rotate = 0;
let scaleX = 1;
let scaleY = 1;
if (orientation > 1) {
self.url = utils.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;
}
self.clone();
}
clone() {
const self = this;
const options = self.options;
const $this = self.$element;
const url = self.url;
let crossOrigin = '';
let crossOriginUrl;
if (options.checkCrossOrigin && utils.isCrossOriginURL(url)) {
crossOrigin = $this.prop('crossOrigin');
if (crossOrigin) {
crossOriginUrl = url;
} else {
crossOrigin = 'anonymous';
// Bust cache (#148) when there is not a "crossOrigin" property
crossOriginUrl = utils.addTimestamp(url);
}
}
self.crossOrigin = crossOrigin;
self.crossOriginUrl = crossOriginUrl;
const $clone = $(`<img ${utils.getCrossOrigin(crossOrigin)} src="${crossOriginUrl || url}">`);
self.$clone = $clone;
if (self.isImg) {
if ($this[0].complete) {
self.start();
} else {
$this.one('load', $.proxy(self.start, this));
}
} else {
$clone.one('load', $.proxy(self.start, this))
.one('error', $.proxy(self.stop, this))
.addClass('cropper-hide')
.insertAfter($this);
}
}
start() {
const self = this;
const $clone = self.$clone;
let $image = self.$element;
if (!self.isImg) {
$clone.off('error', self.stop);
$image = $clone;
}
utils.getImageSize($image[0], (naturalWidth, naturalHeight) => {
$.extend(self.image, {
naturalWidth,
naturalHeight,
aspectRatio: naturalWidth / naturalHeight
});
self.loaded = true;
self.build();
});
}
stop() {
const self = this;
self.$clone.remove();
self.$clone = null;
}
build() {
const self = this;
const options = self.options;
const $this = self.$element;
const $clone = self.$clone;
let $cropper;
let $cropBox;
let $face;
if (!self.loaded) {
return;
}
// Unbuild first when replace
if (self.ready) {
self.unbuild();
}
// Create cropper elements
self.$container = $this.parent();
self.$cropper = $cropper = $(TEMPLATE);
self.$canvas = $cropper.find('.cropper-canvas').append($clone);
self.$dragBox = $cropper.find('.cropper-drag-box');
self.$cropBox = $cropBox = $cropper.find('.cropper-crop-box');
self.$viewBox = $cropper.find('.cropper-view-box');
self.$face = $face = $cropBox.find('.cropper-face');
// Hide the original image
$this.addClass(CLASS_HIDDEN).after($cropper);
// Show the clone image if is hidden
if (!self.isImg) {
$clone.removeClass('cropper-hide');
}
self.initPreview();
self.bind();
options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;
options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;
self.cropped = options.autoCrop;
if (options.autoCrop) {
if (options.modal) {
self.$dragBox.addClass('cropper-modal');
}
} else {
$cropBox.addClass(CLASS_HIDDEN);
}
if (!options.guides) {
$cropBox.find('.cropper-dashed').addClass(CLASS_HIDDEN);
}
if (!options.center) {
$cropBox.find('.cropper-center').addClass(CLASS_HIDDEN);
}
if (options.cropBoxMovable) {
$face.addClass('cropper-move').data('action', 'all');
}
if (!options.highlight) {
$face.addClass('cropper-invisible');
}
if (options.background) {
$cropper.addClass('cropper-bg');
}
if (!options.cropBoxResizable) {
$cropBox.find('.cropper-line, .cropper-point').addClass(CLASS_HIDDEN);
}
self.setDragMode(options.dragMode);
self.render();
self.ready = true;
self.setData(options.data);
// Trigger the ready event asynchronously to keep `data('cropper')` is defined
self.completing = setTimeout(() => {
if ($.isFunction(options.ready)) {
$this.one('ready', options.ready);
}
self.trigger('ready');
self.trigger('crop', self.getData());
self.completed = true;
}, 0);
}
unbuild() {
const self = this;
if (!self.ready) {
return;
}
if (!self.completed) {
clearTimeout(self.completing);
}
self.ready = false;
self.completed = false;
self.initialImage = null;
// Clear `initialCanvas` is necessary when replace
self.initialCanvas = null;
self.initialCropBox = null;
self.container = null;
self.canvas = null;
// Clear `cropBox` is necessary when replace
self.cropBox = null;
self.unbind();
self.resetPreview();
self.$preview = null;
self.$viewBox = null;
self.$cropBox = null;
self.$dragBox = null;
self.$canvas = null;
self.$container = null;
self.$cropper.remove();
self.$cropper = null;
}
static setDefaults(options) {
$.extend(DEFAULTS, $.isPlainObject(options) && options);
}
}
$.extend(Cropper.prototype, render);
$.extend(Cropper.prototype, preview);
$.extend(Cropper.prototype, events);
$.extend(Cropper.prototype, handlers);
$.extend(Cropper.prototype, change);
$.extend(Cropper.prototype, methods);
export default Cropper;