ngx-image-cropper-upgraded
Version:
An image cropper for Angular upgraded by Spymannn
1,987 lines • 76.4 kB
JavaScript
import { EventEmitter, isDevMode, Component, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, Input, HostBinding, Output, HostListener, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { __assign, __spread } from 'tslib';
import { DomSanitizer } from '@angular/platform-browser';
/**
* @fileoverview added by tsickle
* Generated from: lib/utils/exif.utils.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// Black 2x1 JPEG, with the following meta information set:
// - EXIF Orientation: 6 (Rotated 90° CCW)
// Source: https://github.com/blueimp/JavaScript-Load-Image
/** @type {?} */
var testAutoOrientationImageURL = 'data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' +
'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' +
'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' +
'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/x' +
'ABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAA' +
'AAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==';
/**
* @return {?}
*/
function supportsAutomaticRotation() {
return new Promise((/**
* @param {?} resolve
* @return {?}
*/
function (resolve) {
/** @type {?} */
var img = new Image();
img.onload = (/**
* @return {?}
*/
function () {
// Check if browser supports automatic image orientation:
/** @type {?} */
var supported = img.width === 1 && img.height === 2;
resolve(supported);
});
img.src = testAutoOrientationImageURL;
}));
}
/**
* @param {?} exifRotationOrBase64Image
* @return {?}
*/
function getTransformationsFromExifData(exifRotationOrBase64Image) {
if (typeof exifRotationOrBase64Image === 'string') {
exifRotationOrBase64Image = getExifRotation(exifRotationOrBase64Image);
}
switch (exifRotationOrBase64Image) {
case 2: return { rotate: 0, flip: true };
case 3: return { rotate: 2, flip: false };
case 4: return { rotate: 2, flip: true };
case 5: return { rotate: 1, flip: true };
case 6: return { rotate: 1, flip: false };
case 7: return { rotate: 3, flip: true };
case 8: return { rotate: 3, flip: false };
default: return { rotate: 0, flip: false };
}
}
/**
* @param {?} imageBase64
* @return {?}
*/
function getExifRotation(imageBase64) {
/** @type {?} */
var view = new DataView(base64ToArrayBuffer(imageBase64));
if (view.getUint16(0, false) != 0xFFD8) {
return -2;
}
/** @type {?} */
var length = view.byteLength;
/** @type {?} */
var offset = 2;
while (offset < length) {
if (view.getUint16(offset + 2, false) <= 8)
return -1;
/** @type {?} */
var marker = view.getUint16(offset, false);
offset += 2;
if (marker == 0xFFE1) {
if (view.getUint32(offset += 2, false) != 0x45786966) {
return -1;
}
/** @type {?} */
var little = view.getUint16(offset += 6, false) == 0x4949;
offset += view.getUint32(offset + 4, little);
/** @type {?} */
var tags = view.getUint16(offset, little);
offset += 2;
for (var i = 0; i < tags; i++) {
if (view.getUint16(offset + (i * 12), little) == 0x0112) {
return view.getUint16(offset + (i * 12) + 8, little);
}
}
}
else if ((marker & 0xFF00) != 0xFF00) {
break;
}
else {
offset += view.getUint16(offset, false);
}
}
return -1;
}
/**
* @param {?} imageBase64
* @return {?}
*/
function base64ToArrayBuffer(imageBase64) {
imageBase64 = imageBase64.replace(/^data\:([^\;]+)\;base64,/gmi, '');
/** @type {?} */
var binaryString = atob(imageBase64);
/** @type {?} */
var len = binaryString.length;
/** @type {?} */
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
/**
* @fileoverview added by tsickle
* Generated from: lib/utils/resize.utils.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/*
* Hermite resize - fast image resize/resample using Hermite filter.
* https://github.com/viliusle/Hermite-resize
*/
/**
* @param {?} canvas
* @param {?} width
* @param {?} height
* @return {?}
*/
function resizeCanvas(canvas, width, height) {
/** @type {?} */
var width_source = canvas.width;
/** @type {?} */
var height_source = canvas.height;
width = Math.round(width);
height = Math.round(height);
/** @type {?} */
var ratio_w = width_source / width;
/** @type {?} */
var ratio_h = height_source / height;
/** @type {?} */
var ratio_w_half = Math.ceil(ratio_w / 2);
/** @type {?} */
var ratio_h_half = Math.ceil(ratio_h / 2);
/** @type {?} */
var ctx = canvas.getContext('2d');
if (ctx) {
/** @type {?} */
var img = ctx.getImageData(0, 0, width_source, height_source);
/** @type {?} */
var img2 = ctx.createImageData(width, height);
/** @type {?} */
var data = img.data;
/** @type {?} */
var data2 = img2.data;
for (var j = 0; j < height; j++) {
for (var i = 0; i < width; i++) {
/** @type {?} */
var x2 = (i + j * width) * 4;
/** @type {?} */
var center_y = j * ratio_h;
/** @type {?} */
var weight = 0;
/** @type {?} */
var weights = 0;
/** @type {?} */
var weights_alpha = 0;
/** @type {?} */
var gx_r = 0;
/** @type {?} */
var gx_g = 0;
/** @type {?} */
var gx_b = 0;
/** @type {?} */
var gx_a = 0;
/** @type {?} */
var xx_start = Math.floor(i * ratio_w);
/** @type {?} */
var yy_start = Math.floor(j * ratio_h);
/** @type {?} */
var xx_stop = Math.ceil((i + 1) * ratio_w);
/** @type {?} */
var yy_stop = Math.ceil((j + 1) * ratio_h);
xx_stop = Math.min(xx_stop, width_source);
yy_stop = Math.min(yy_stop, height_source);
for (var yy = yy_start; yy < yy_stop; yy++) {
/** @type {?} */
var dy = Math.abs(center_y - yy) / ratio_h_half;
/** @type {?} */
var center_x = i * ratio_w;
/** @type {?} */
var w0 = dy * dy;
for (var xx = xx_start; xx < xx_stop; xx++) {
/** @type {?} */
var dx = Math.abs(center_x - xx) / ratio_w_half;
/** @type {?} */
var w = Math.sqrt(w0 + dx * dx);
if (w >= 1) {
//pixel too far
continue;
}
//hermite filter
weight = 2 * w * w * w - 3 * w * w + 1;
/** @type {?} */
var pos_x = 4 * (xx + yy * width_source);
//alpha
gx_a += weight * data[pos_x + 3];
weights_alpha += weight;
//colors
if (data[pos_x + 3] < 255)
weight = weight * data[pos_x + 3] / 250;
gx_r += weight * data[pos_x];
gx_g += weight * data[pos_x + 1];
gx_b += weight * data[pos_x + 2];
weights += weight;
}
}
data2[x2] = gx_r / weights;
data2[x2 + 1] = gx_g / weights;
data2[x2 + 2] = gx_b / weights;
data2[x2 + 3] = gx_a / weights_alpha;
}
}
canvas.width = width;
canvas.height = height;
//draw
ctx.putImageData(img2, 0, 0);
}
}
/**
* @fileoverview added by tsickle
* Generated from: lib/interfaces/move-start.interface.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @record
*/
function MoveStart() { }
if (false) {
/** @type {?} */
MoveStart.prototype.active;
/** @type {?} */
MoveStart.prototype.type;
/** @type {?} */
MoveStart.prototype.position;
/** @type {?} */
MoveStart.prototype.x1;
/** @type {?} */
MoveStart.prototype.y1;
/** @type {?} */
MoveStart.prototype.x2;
/** @type {?} */
MoveStart.prototype.y2;
/** @type {?} */
MoveStart.prototype.clientX;
/** @type {?} */
MoveStart.prototype.clientY;
}
/** @enum {string} */
var MoveTypes = {
Move: "move",
Resize: "resize",
Pinch: "pinch",
};
/**
* @fileoverview added by tsickle
* Generated from: lib/component/image-cropper.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var ImageCropperComponent = /** @class */ (function () {
function ImageCropperComponent(sanitizer, cd) {
this.sanitizer = sanitizer;
this.cd = cd;
this.Hammer = typeof window !== 'undefined'
? (/** @type {?} */ (((/** @type {?} */ (window))).Hammer))
: null;
this.setImageMaxSizeRetries = 0;
this.cropperScaledMinWidth = 20;
this.cropperScaledMinHeight = 20;
this.cropperScaledMaxWidth = 20;
this.cropperScaledMaxHeight = 20;
this.exifTransform = { rotate: 0, flip: false };
this.autoRotateSupported = supportsAutomaticRotation();
this.stepSize = 3;
this.marginLeft = '0px';
this.imageVisible = false;
this.moveTypes = MoveTypes;
this.format = 'png';
this.maintainAspectRatio = true;
this.transform = {};
this.aspectRatio = 1;
this.resizeToWidth = 0;
this.resizeToHeight = 0;
this.cropperMinWidth = 0;
this.cropperMinHeight = 0;
this.cropperMaxHeight = 0;
this.cropperMaxWidth = 0;
this.cropperStaticWidth = 0;
this.cropperStaticHeight = 0;
this.canvasRotation = 0;
this.initialStepSize = 3;
this.roundCropper = false;
this.onlyScaleDown = false;
this.imageQuality = 92;
this.autoCrop = true;
this.containWithinAspectRatio = false;
this.hideResizeSquares = false;
this.cropper = {
x1: -100,
y1: -100,
x2: 10000,
y2: 10000
};
this.alignImage = 'center';
this.disabled = false;
this.imageCropped = new EventEmitter();
this.startCropImage = new EventEmitter();
this.imageLoaded = new EventEmitter();
this.cropperReady = new EventEmitter();
this.loadImageFailed = new EventEmitter();
this.initCropper();
}
/**
* @param {?} changes
* @return {?}
*/
ImageCropperComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
if (this.cropperStaticHeight && this.cropperStaticWidth) {
this.hideResizeSquares = true;
this.cropperMinWidth = this.cropperStaticWidth;
this.cropperMinHeight = this.cropperStaticHeight;
this.cropperMaxHeight = this.cropperStaticHeight;
this.cropperMaxWidth = this.cropperStaticWidth;
this.maintainAspectRatio = false;
}
this.onChangesInputImage(changes);
if (this.originalImage && this.originalImage.complete && this.exifTransform
&& (changes.containWithinAspectRatio || changes.canvasRotation)) {
this.transformOriginalImage();
}
if (changes.cropper) {
this.setMaxSize();
this.setCropperScaledMinSize();
this.setCropperScaledMaxSize();
this.checkCropperPosition(false);
this.doAutoCrop();
this.cd.markForCheck();
}
if (changes.aspectRatio && this.imageVisible) {
this.resetCropperPosition();
}
if (changes.transform) {
this.transform = this.transform || {};
this.setCssTransform();
this.doAutoCrop();
}
};
/**
* @private
* @param {?} changes
* @return {?}
*/
ImageCropperComponent.prototype.onChangesInputImage = /**
* @private
* @param {?} changes
* @return {?}
*/
function (changes) {
if (changes.imageChangedEvent || changes.imageURL || changes.imageBase64 || changes.imageFile) {
this.initCropper();
}
if (changes.imageChangedEvent && this.isValidImageChangedEvent()) {
this.loadImageFile(this.imageChangedEvent.target.files[0]);
}
if (changes.imageURL && this.imageURL) {
this.loadImageFromURL(this.imageURL);
}
if (changes.imageBase64 && this.imageBase64) {
this.loadBase64Image(this.imageBase64);
}
if (changes.imageFile && this.imageFile) {
this.loadImageFile(this.imageFile);
}
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.isValidImageChangedEvent = /**
* @private
* @return {?}
*/
function () {
return this.imageChangedEvent
&& this.imageChangedEvent.target
&& this.imageChangedEvent.target.files
&& this.imageChangedEvent.target.files.length > 0;
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.setCssTransform = /**
* @private
* @return {?}
*/
function () {
this.safeTransformStyle = this.sanitizer.bypassSecurityTrustStyle('scaleX(' + (this.transform.scale || 1) * (this.transform.flipH ? -1 : 1) + ')' +
'scaleY(' + (this.transform.scale || 1) * (this.transform.flipV ? -1 : 1) + ')' +
'rotate(' + (this.transform.rotate || 0) + 'deg)');
};
/**
* @return {?}
*/
ImageCropperComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.stepSize = this.initialStepSize;
this.activatePinchGesture();
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.initCropper = /**
* @private
* @return {?}
*/
function () {
this.imageVisible = false;
this.transformedImage = null;
this.safeImgDataUrl = 'data:image/png;base64,iVBORw0KGg'
+ 'oAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAU'
+ 'AAarVyFEAAAAASUVORK5CYII=';
this.moveStart = {
active: false,
type: null,
position: null,
x1: 0,
y1: 0,
x2: 0,
y2: 0,
clientX: 0,
clientY: 0
};
this.maxSize = {
width: 0,
height: 0
};
this.originalSize = {
width: 0,
height: 0
};
this.transformedSize = {
width: 0,
height: 0
};
this.cropper.x1 = -100;
this.cropper.y1 = -100;
this.cropper.x2 = 10000;
this.cropper.y2 = 10000;
};
/**
* @private
* @param {?} imageBase64
* @param {?} imageType
* @return {?}
*/
ImageCropperComponent.prototype.loadImage = /**
* @private
* @param {?} imageBase64
* @param {?} imageType
* @return {?}
*/
function (imageBase64, imageType) {
if (this.isValidImageType(imageType)) {
this.loadBase64Image(imageBase64);
}
else {
this.loadImageFailed.emit();
}
};
/**
* @private
* @param {?} file
* @return {?}
*/
ImageCropperComponent.prototype.loadImageFile = /**
* @private
* @param {?} file
* @return {?}
*/
function (file) {
var _this = this;
/** @type {?} */
var fileReader = new FileReader();
fileReader.onload = (/**
* @param {?} event
* @return {?}
*/
function (event) { return _this.loadImage(event.target.result, file.type); });
fileReader.readAsDataURL(file);
};
/**
* @private
* @param {?} type
* @return {?}
*/
ImageCropperComponent.prototype.isValidImageType = /**
* @private
* @param {?} type
* @return {?}
*/
function (type) {
return /image\/(png|jpg|jpeg|bmp|gif|tiff|webp)/.test(type);
};
/**
* @private
* @param {?} imageBase64
* @return {?}
*/
ImageCropperComponent.prototype.loadBase64Image = /**
* @private
* @param {?} imageBase64
* @return {?}
*/
function (imageBase64) {
var _this = this;
this.autoRotateSupported
.then((/**
* @param {?} supported
* @return {?}
*/
function (supported) { return _this.checkExifAndLoadBase64Image(imageBase64, supported); }))
.then((/**
* @return {?}
*/
function () { return _this.transformOriginalImage(); }))
.catch((/**
* @param {?} error
* @return {?}
*/
function (error) {
_this.loadImageFailed.emit();
_this.originalImage = null;
_this.originalBase64 = null;
console.error(error);
}));
};
/**
* @private
* @param {?} imageBase64
* @param {?} autoRotateSupported
* @return {?}
*/
ImageCropperComponent.prototype.checkExifAndLoadBase64Image = /**
* @private
* @param {?} imageBase64
* @param {?} autoRotateSupported
* @return {?}
*/
function (imageBase64, autoRotateSupported) {
var _this = this;
return new Promise((/**
* @param {?} resolve
* @param {?} reject
* @return {?}
*/
function (resolve, reject) {
_this.originalImage = new Image();
_this.originalImage.onload = (/**
* @return {?}
*/
function () {
_this.originalBase64 = imageBase64;
_this.exifTransform = getTransformationsFromExifData(autoRotateSupported ? -1 : imageBase64);
_this.originalSize.width = _this.originalImage.naturalWidth;
_this.originalSize.height = _this.originalImage.naturalHeight;
resolve();
});
_this.originalImage.onerror = reject;
_this.originalImage.src = imageBase64;
}));
};
/**
* @private
* @param {?} url
* @return {?}
*/
ImageCropperComponent.prototype.loadImageFromURL = /**
* @private
* @param {?} url
* @return {?}
*/
function (url) {
var _this = this;
/** @type {?} */
var img = new Image();
img.onerror = (/**
* @return {?}
*/
function () { return _this.loadImageFailed.emit(); });
img.onload = (/**
* @return {?}
*/
function () {
/** @type {?} */
var canvas = document.createElement('canvas');
/** @type {?} */
var context = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0);
_this.loadBase64Image(canvas.toDataURL());
});
img.crossOrigin = 'anonymous';
img.src = url;
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.transformOriginalImage = /**
* @private
* @return {?}
*/
function () {
if (!this.originalImage || !this.originalImage.complete || !this.exifTransform) {
return Promise.reject(new Error('No image loaded'));
}
/** @type {?} */
var transformedBase64 = this.transformImageBase64();
return this.setTransformedImage(transformedBase64);
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.transformImageBase64 = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var canvasRotation = this.canvasRotation + this.exifTransform.rotate;
if (canvasRotation === 0 && !this.exifTransform.flip && !this.containWithinAspectRatio) {
return this.originalBase64;
}
/** @type {?} */
var transformedSize = this.getTransformedSize();
/** @type {?} */
var canvas = document.createElement('canvas');
canvas.width = transformedSize.width;
canvas.height = transformedSize.height;
/** @type {?} */
var ctx = canvas.getContext('2d');
ctx.setTransform(this.exifTransform.flip ? -1 : 1, 0, 0, 1, canvas.width / 2, canvas.height / 2);
ctx.rotate(Math.PI * (canvasRotation / 2));
ctx.drawImage(this.originalImage, -this.originalSize.width / 2, -this.originalSize.height / 2);
return canvas.toDataURL();
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.getTransformedSize = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var canvasRotation = this.canvasRotation + this.exifTransform.rotate;
if (this.containWithinAspectRatio) {
if (canvasRotation % 2) {
/** @type {?} */
var minWidthToContain = this.originalSize.width * this.aspectRatio;
/** @type {?} */
var minHeightToContain = this.originalSize.height / this.aspectRatio;
return {
width: Math.max(this.originalSize.height, minWidthToContain),
height: Math.max(this.originalSize.width, minHeightToContain),
};
}
else {
/** @type {?} */
var minWidthToContain = this.originalSize.height * this.aspectRatio;
/** @type {?} */
var minHeightToContain = this.originalSize.width / this.aspectRatio;
return {
width: Math.max(this.originalSize.width, minWidthToContain),
height: Math.max(this.originalSize.height, minHeightToContain),
};
}
}
if (canvasRotation % 2) {
return {
height: this.originalSize.width,
width: this.originalSize.height,
};
}
return {
width: this.originalSize.width,
height: this.originalSize.height,
};
};
/**
* @private
* @param {?} transformedBase64
* @return {?}
*/
ImageCropperComponent.prototype.setTransformedImage = /**
* @private
* @param {?} transformedBase64
* @return {?}
*/
function (transformedBase64) {
var _this = this;
return new Promise((/**
* @param {?} resolve
* @return {?}
*/
function (resolve) {
_this.transformedBase64 = transformedBase64;
_this.safeImgDataUrl = _this.sanitizer.bypassSecurityTrustResourceUrl(transformedBase64);
_this.transformedImage = new Image();
_this.transformedImage.onload = (/**
* @return {?}
*/
function () {
_this.transformedSize.width = _this.transformedImage.naturalWidth;
_this.transformedSize.height = _this.transformedImage.naturalHeight;
_this.cd.markForCheck();
resolve();
});
_this.transformedImage.src = _this.transformedBase64;
}));
};
/**
* @return {?}
*/
ImageCropperComponent.prototype.imageLoadedInView = /**
* @return {?}
*/
function () {
var _this = this;
if (this.transformedImage != null) {
this.imageLoaded.emit(this.transformedImage);
this.setImageMaxSizeRetries = 0;
setTimeout((/**
* @return {?}
*/
function () { return _this.checkImageMaxSizeRecursively(); }));
}
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.checkImageMaxSizeRecursively = /**
* @private
* @return {?}
*/
function () {
var _this = this;
if (this.setImageMaxSizeRetries > 40) {
this.loadImageFailed.emit();
}
else if (this.sourceImageLoaded()) {
this.setMaxSize();
this.setCropperScaledMinSize();
this.setCropperScaledMaxSize();
this.resetCropperPosition();
this.cropperReady.emit(__assign({}, this.maxSize));
this.cd.markForCheck();
}
else {
this.setImageMaxSizeRetries++;
setTimeout((/**
* @return {?}
*/
function () { return _this.checkImageMaxSizeRecursively(); }), 50);
}
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.sourceImageLoaded = /**
* @private
* @return {?}
*/
function () {
return this.sourceImage && this.sourceImage.nativeElement && this.sourceImage.nativeElement.offsetWidth > 0;
};
/**
* @return {?}
*/
ImageCropperComponent.prototype.onResize = /**
* @return {?}
*/
function () {
this.resizeCropperPosition();
this.setMaxSize();
this.setCropperScaledMinSize();
this.setCropperScaledMaxSize();
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.activatePinchGesture = /**
* @private
* @return {?}
*/
function () {
if (this.Hammer) {
/** @type {?} */
var hammer = new this.Hammer(this.wrapper.nativeElement);
hammer.get('pinch').set({ enable: true });
hammer.on('pinchmove', this.onPinch.bind(this));
hammer.on('pinchend', this.pinchStop.bind(this));
hammer.on('pinchstart', this.startPinch.bind(this));
}
else if (isDevMode()) {
console.warn('[NgxImageCropper] Could not find HammerJS - Pinch Gesture won\'t work');
}
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.resizeCropperPosition = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var sourceImageElement = this.sourceImage.nativeElement;
if (this.maxSize.width !== sourceImageElement.offsetWidth || this.maxSize.height !== sourceImageElement.offsetHeight) {
this.cropper.x1 = this.cropper.x1 * sourceImageElement.offsetWidth / this.maxSize.width;
this.cropper.x2 = this.cropper.x2 * sourceImageElement.offsetWidth / this.maxSize.width;
this.cropper.y1 = this.cropper.y1 * sourceImageElement.offsetHeight / this.maxSize.height;
this.cropper.y2 = this.cropper.y2 * sourceImageElement.offsetHeight / this.maxSize.height;
}
};
/**
* @return {?}
*/
ImageCropperComponent.prototype.resetCropperPosition = /**
* @return {?}
*/
function () {
/** @type {?} */
var sourceImageElement = this.sourceImage.nativeElement;
if (this.cropperStaticHeight && this.cropperStaticWidth) {
this.cropper.x1 = 0;
this.cropper.x2 = sourceImageElement.offsetWidth > this.cropperStaticWidth ?
this.cropperStaticWidth : sourceImageElement.offsetWidth;
this.cropper.y1 = 0;
this.cropper.y2 = sourceImageElement.offsetHeight > this.cropperStaticHeight ?
this.cropperStaticHeight : sourceImageElement.offsetHeight;
}
else {
/** @type {?} */
var cropperWidth = Math.min(this.cropperScaledMaxWidth, sourceImageElement.offsetWidth);
/** @type {?} */
var cropperHeight = Math.min(this.cropperScaledMaxHeight, sourceImageElement.offsetHeight);
if (!this.maintainAspectRatio) {
this.cropper.x1 = 0;
this.cropper.x2 = cropperWidth;
this.cropper.y1 = 0;
this.cropper.y2 = cropperHeight;
}
else if (cropperWidth / this.aspectRatio < cropperHeight) {
this.cropper.x1 = 0;
this.cropper.x2 = cropperWidth;
/** @type {?} */
var cropperHeightWithAspectRatio = cropperWidth / this.aspectRatio;
this.cropper.y1 = (cropperHeight - cropperHeightWithAspectRatio) / 2;
this.cropper.y2 = this.cropper.y1 + cropperHeightWithAspectRatio;
}
else {
this.cropper.y1 = 0;
this.cropper.y2 = cropperHeight;
/** @type {?} */
var cropperWidthWithAspectRatio = cropperHeight * this.aspectRatio;
this.cropper.x1 = (cropperWidth - cropperWidthWithAspectRatio) / 2;
this.cropper.x2 = this.cropper.x1 + cropperWidthWithAspectRatio;
}
}
this.doAutoCrop();
this.imageVisible = true;
};
/**
* @param {?} event
* @return {?}
*/
ImageCropperComponent.prototype.keyboardAccess = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.changeKeyboardStepSize(event);
this.keyboardMoveCropper(event);
};
/**
* @private
* @param {?} event
* @return {?}
*/
ImageCropperComponent.prototype.changeKeyboardStepSize = /**
* @private
* @param {?} event
* @return {?}
*/
function (event) {
if (event.key >= '1' && event.key <= '9') {
this.stepSize = +event.key;
return;
}
};
/**
* @private
* @param {?} event
* @return {?}
*/
ImageCropperComponent.prototype.keyboardMoveCropper = /**
* @private
* @param {?} event
* @return {?}
*/
function (event) {
/** @type {?} */
var keyboardWhiteList = ['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft'];
if (!(keyboardWhiteList.includes(event.key))) {
return;
}
/** @type {?} */
var moveType = event.shiftKey ? MoveTypes.Resize : MoveTypes.Move;
/** @type {?} */
var position = event.altKey ? this.getInvertedPositionForKey(event.key) : this.getPositionForKey(event.key);
/** @type {?} */
var moveEvent = this.getEventForKey(event.key, this.stepSize);
event.preventDefault();
event.stopPropagation();
this.startMove({ clientX: 0, clientY: 0 }, moveType, position);
this.moveImg(moveEvent);
this.moveStop();
};
/**
* @private
* @param {?} key
* @return {?}
*/
ImageCropperComponent.prototype.getPositionForKey = /**
* @private
* @param {?} key
* @return {?}
*/
function (key) {
switch (key) {
case 'ArrowUp':
return 'top';
case 'ArrowRight':
return 'right';
case 'ArrowDown':
return 'bottom';
case 'ArrowLeft':
default:
return 'left';
}
};
/**
* @private
* @param {?} key
* @return {?}
*/
ImageCropperComponent.prototype.getInvertedPositionForKey = /**
* @private
* @param {?} key
* @return {?}
*/
function (key) {
switch (key) {
case 'ArrowUp':
return 'bottom';
case 'ArrowRight':
return 'left';
case 'ArrowDown':
return 'top';
case 'ArrowLeft':
default:
return 'right';
}
};
/**
* @private
* @param {?} key
* @param {?} stepSize
* @return {?}
*/
ImageCropperComponent.prototype.getEventForKey = /**
* @private
* @param {?} key
* @param {?} stepSize
* @return {?}
*/
function (key, stepSize) {
switch (key) {
case 'ArrowUp':
return { clientX: 0, clientY: stepSize * -1 };
case 'ArrowRight':
return { clientX: stepSize, clientY: 0 };
case 'ArrowDown':
return { clientX: 0, clientY: stepSize };
case 'ArrowLeft':
default:
return { clientX: stepSize * -1, clientY: 0 };
}
};
/**
* @param {?} event
* @param {?} moveType
* @param {?=} position
* @return {?}
*/
ImageCropperComponent.prototype.startMove = /**
* @param {?} event
* @param {?} moveType
* @param {?=} position
* @return {?}
*/
function (event, moveType, position) {
if (position === void 0) { position = null; }
if (this.moveStart && this.moveStart.active && this.moveStart.type === MoveTypes.Pinch) {
return;
}
if (event.preventDefault) {
event.preventDefault();
}
this.moveStart = __assign({ active: true, type: moveType, position: position, clientX: this.getClientX(event), clientY: this.getClientY(event) }, this.cropper);
};
/**
* @param {?} event
* @return {?}
*/
ImageCropperComponent.prototype.startPinch = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (!this.safeImgDataUrl) {
return;
}
if (event.preventDefault) {
event.preventDefault();
}
this.moveStart = __assign({ active: true, type: MoveTypes.Pinch, position: 'center', clientX: this.cropper.x1 + (this.cropper.x2 - this.cropper.x1) / 2, clientY: this.cropper.y1 + (this.cropper.y2 - this.cropper.y1) / 2 }, this.cropper);
};
/**
* @param {?} event
* @return {?}
*/
ImageCropperComponent.prototype.moveImg = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (this.moveStart.active) {
if (event.stopPropagation) {
event.stopPropagation();
}
if (event.preventDefault) {
event.preventDefault();
}
if (this.moveStart.type === MoveTypes.Move) {
this.move(event);
this.checkCropperPosition(true);
}
else if (this.moveStart.type === MoveTypes.Resize) {
if (!this.cropperStaticWidth && !this.cropperStaticHeight) {
this.resize(event);
}
this.checkCropperPosition(false);
}
this.cd.detectChanges();
}
};
/**
* @param {?} event
* @return {?}
*/
ImageCropperComponent.prototype.onPinch = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (this.moveStart.active) {
if (event.stopPropagation) {
event.stopPropagation();
}
if (event.preventDefault) {
event.preventDefault();
}
if (this.moveStart.type === MoveTypes.Pinch) {
this.resize(event);
this.checkCropperPosition(false);
}
this.cd.detectChanges();
}
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.setMaxSize = /**
* @private
* @return {?}
*/
function () {
if (this.sourceImage) {
/** @type {?} */
var sourceImageElement = this.sourceImage.nativeElement;
this.maxSize.width = sourceImageElement.offsetWidth;
this.maxSize.height = sourceImageElement.offsetHeight;
this.marginLeft = this.sanitizer.bypassSecurityTrustStyle('calc(50% - ' + this.maxSize.width / 2 + 'px)');
}
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.setCropperScaledMinSize = /**
* @private
* @return {?}
*/
function () {
if (this.transformedImage) {
this.setCropperScaledMinWidth();
this.setCropperScaledMinHeight();
}
else {
this.cropperScaledMinWidth = 20;
this.cropperScaledMinHeight = 20;
}
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.setCropperScaledMinWidth = /**
* @private
* @return {?}
*/
function () {
this.cropperScaledMinWidth = this.cropperMinWidth > 0
? Math.max(20, this.cropperMinWidth / this.transformedImage.width * this.maxSize.width)
: 20;
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.setCropperScaledMinHeight = /**
* @private
* @return {?}
*/
function () {
if (this.maintainAspectRatio) {
this.cropperScaledMinHeight = Math.max(20, this.cropperScaledMinWidth / this.aspectRatio);
}
else if (this.cropperMinHeight > 0) {
this.cropperScaledMinHeight = Math.max(20, this.cropperMinHeight / this.transformedImage.height * this.maxSize.height);
}
else {
this.cropperScaledMinHeight = 20;
}
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.setCropperScaledMaxSize = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var sourceImageElement = this.sourceImage.nativeElement;
/** @type {?} */
var ratio = this.transformedSize.width / sourceImageElement.offsetWidth;
this.cropperScaledMaxWidth = this.cropperMaxWidth > 20 ? this.cropperMaxWidth : this.maxSize.width;
this.cropperScaledMaxHeight = this.cropperMaxHeight > 20 ? this.cropperMaxHeight : this.maxSize.height;
if (ratio != 1 && (this.cropperMaxWidth > 20 || this.cropperMaxHeight > 20)) {
this.cropperScaledMaxWidth = this.cropperScaledMaxWidth / ratio;
this.cropperScaledMaxHeight = this.cropperScaledMaxHeight / ratio;
}
if (this.transformedImage && this.maintainAspectRatio) {
if (this.cropperScaledMaxWidth > this.cropperScaledMaxHeight * this.aspectRatio) {
this.cropperScaledMaxWidth = this.cropperScaledMaxHeight * this.aspectRatio;
}
else if (this.cropperScaledMaxWidth < this.cropperScaledMaxHeight * this.aspectRatio) {
this.cropperScaledMaxHeight = this.cropperScaledMaxWidth / this.aspectRatio;
}
}
};
/**
* @private
* @param {?=} maintainSize
* @return {?}
*/
ImageCropperComponent.prototype.checkCropperPosition = /**
* @private
* @param {?=} maintainSize
* @return {?}
*/
function (maintainSize) {
if (maintainSize === void 0) { maintainSize = false; }
if (this.cropper.x1 < 0) {
this.cropper.x2 -= maintainSize ? this.cropper.x1 : 0;
this.cropper.x1 = 0;
}
if (this.cropper.y1 < 0) {
this.cropper.y2 -= maintainSize ? this.cropper.y1 : 0;
this.cropper.y1 = 0;
}
if (this.cropper.x2 > this.maxSize.width) {
this.cropper.x1 -= maintainSize ? (this.cropper.x2 - this.maxSize.width) : 0;
this.cropper.x2 = this.maxSize.width;
}
if (this.cropper.y2 > this.maxSize.height) {
this.cropper.y1 -= maintainSize ? (this.cropper.y2 - this.maxSize.height) : 0;
this.cropper.y2 = this.maxSize.height;
}
};
/**
* @return {?}
*/
ImageCropperComponent.prototype.moveStop = /**
* @return {?}
*/
function () {
if (this.moveStart.active) {
this.moveStart.active = false;
this.doAutoCrop();
}
};
/**
* @return {?}
*/
ImageCropperComponent.prototype.pinchStop = /**
* @return {?}
*/
function () {
if (this.moveStart.active) {
this.moveStart.active = false;
this.doAutoCrop();
}
};
/**
* @private
* @param {?} event
* @return {?}
*/
ImageCropperComponent.prototype.move = /**
* @private
* @param {?} event
* @return {?}
*/
function (event) {
/** @type {?} */
var diffX = this.getClientX(event) - this.moveStart.clientX;
/** @type {?} */
var diffY = this.getClientY(event) - this.moveStart.clientY;
this.cropper.x1 = this.moveStart.x1 + diffX;
this.cropper.y1 = this.moveStart.y1 + diffY;
this.cropper.x2 = this.moveStart.x2 + diffX;
this.cropper.y2 = this.moveStart.y2 + diffY;
};
/**
* @private
* @param {?} event
* @return {?}
*/
ImageCropperComponent.prototype.resize = /**
* @private
* @param {?} event
* @return {?}
*/
function (event) {
/** @type {?} */
var diffX = this.getClientX(event) - this.moveStart.clientX;
/** @type {?} */
var diffY = this.getClientY(event) - this.moveStart.clientY;
switch (this.moveStart.position) {
case 'left':
this.cropper.x1 = Math.min(Math.max(this.moveStart.x1 + diffX, this.cropper.x2 - this.cropperScaledMaxWidth), this.cropper.x2 - this.cropperScaledMinWidth);
break;
case 'topleft':
this.cropper.x1 = Math.min(Math.max(this.moveStart.x1 + diffX, this.cropper.x2 - this.cropperScaledMaxWidth), this.cropper.x2 - this.cropperScaledMinWidth);
this.cropper.y1 = Math.min(Math.max(this.moveStart.y1 + diffY, this.cropper.y2 - this.cropperScaledMaxHeight), this.cropper.y2 - this.cropperScaledMinHeight);
break;
case 'top':
this.cropper.y1 = Math.min(Math.max(this.moveStart.y1 + diffY, this.cropper.y2 - this.cropperScaledMaxHeight), this.cropper.y2 - this.cropperScaledMinHeight);
break;
case 'topright':
this.cropper.x2 = Math.max(Math.min(this.moveStart.x2 + diffX, this.cropper.x1 + this.cropperScaledMaxWidth), this.cropper.x1 + this.cropperScaledMinWidth);
this.cropper.y1 = Math.min(Math.max(this.moveStart.y1 + diffY, this.cropper.y2 - this.cropperScaledMaxHeight), this.cropper.y2 - this.cropperScaledMinHeight);
break;
case 'right':
this.cropper.x2 = Math.max(Math.min(this.moveStart.x2 + diffX, this.cropper.x1 + this.cropperScaledMaxWidth), this.cropper.x1 + this.cropperScaledMinWidth);
break;
case 'bottomright':
this.cropper.x2 = Math.max(Math.min(this.moveStart.x2 + diffX, this.cropper.x1 + this.cropperScaledMaxWidth), this.cropper.x1 + this.cropperScaledMinWidth);
this.cropper.y2 = Math.max(Math.min(this.moveStart.y2 + diffY, this.cropper.y1 + this.cropperScaledMaxHeight), this.cropper.y1 + this.cropperScaledMinHeight);
break;
case 'bottom':
this.cropper.y2 = Math.max(Math.min(this.moveStart.y2 + diffY, this.cropper.y1 + this.cropperScaledMaxHeight), this.cropper.y1 + this.cropperScaledMinHeight);
break;
case 'bottomleft':
this.cropper.x1 = Math.min(Math.max(this.moveStart.x1 + diffX, this.cropper.x2 - this.cropperScaledMaxWidth), this.cropper.x2 - this.cropperScaledMinWidth);
this.cropper.y2 = Math.max(Math.min(this.moveStart.y2 + diffY, this.cropper.y1 + this.cropperScaledMaxHeight), this.cropper.y1 + this.cropperScaledMinHeight);
break;
case 'center':
/** @type {?} */
var scale = event.scale;
/** @type {?} */
var newWidth = (Math.abs(this.moveStart.x2 - this.moveStart.x1)) * scale;
/** @type {?} */
var newHeight = (Math.abs(this.moveStart.y2 - this.moveStart.y1)) * scale;
/** @type {?} */
var x1 = this.cropper.x1;
/** @type {?} */
var y1 = this.cropper.y1;
this.cropper.x1 = Math.min(Math.max(this.moveStart.clientX - (newWidth / 2), this.cropper.x2 - this.cropperScaledMaxWidth / 2), this.cropper.x2 - this.cropperScaledMinWidth);
this.cropper.y1 = Math.min(Math.max(this.moveStart.clientY - (newHeight / 2), this.cropper.y2 - this.cropperScaledMaxHeight / 2), this.cropper.y2 - this.cropperScaledMinHeight);
this.cropper.x2 = Math.max(Math.min(this.moveStart.clientX + (newWidth / 2), x1 + this.cropperScaledMaxWidth / 2), x1 + this.cropperScaledMinWidth);
this.cropper.y2 = Math.max(Math.min(this.moveStart.clientY + (newHeight / 2), y1 + this.cropperScaledMaxHeight / 2), y1 + this.cropperScaledMinHeight);
break;
}
if (this.maintainAspectRatio) {
this.checkAspectRatio();
}
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.checkAspectRatio = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var overflowX = 0;
/** @type {?} */
var overflowY = 0;
switch (this.moveStart.position) {
case 'top':
this.cropper.x2 = this.cropper.x1 + (this.cropper.y2 - this.cropper.y1) * this.aspectRatio;
overflowX = Math.max(this.cropper.x2 - this.maxSize.width, 0);
overflowY = Math.max(0 - this.cropper.y1, 0);
if (overflowX > 0 || overflowY > 0) {
this.cropper.x2 -= (overflowY * this.aspectRatio) > overflowX ? (overflowY * this.aspectRatio) : overflowX;
this.cropper.y1 += (overflowY * this.aspectRatio) > overflowX ? overflowY : overflowX / this.aspectRatio;
}
break;
case 'bottom':
this.cropper.x2 = this.cropper.x1 + (this.cropper.y2 - this.cropper.y1) * this.aspectRatio;
overflowX = Math.max(this.cropper.x2 - this.maxSize.width, 0);
overflowY = Math.max(this.cropper.y2 - this.maxSize.height, 0);
if (overflowX > 0 || overflowY > 0) {
this.cropper.x2 -= (overflowY * this.aspectRatio) > overflowX ? (overflowY * this.aspectRatio) : overflowX;
this.cropper.y2 -= (overflowY * this.aspectRatio) > overflowX ? overflowY : (overflowX / this.aspectRatio);
}
break;
case 'topleft':
this.cropper.y1 = this.cropper.y2 - (this.cropper.x2 - this.cropper.x1) / this.aspectRatio;
overflowX = Math.max(0 - this.cropper.x1, 0);
overflowY = Math.max(0 - this.cropper.y1, 0);
if (overflowX > 0 || overflowY > 0) {
this.cropper.x1 += (overflowY * this.aspectRatio) > overflowX ? (overflowY * this.aspectRatio) : overflowX;
this.cropper.y1 += (overflowY * this.aspectRatio) > overflowX ? overflowY : overflowX / this.aspectRatio;
}
break;
case 'topright':
this.cropper.y1 = this.cropper.y2 - (this.cropper.x2 - this.cropper.x1) / this.aspectRatio;
overflowX = Math.max(this.cropper.x2 - this.maxSize.width, 0);
overflowY = Math.max(0 - this.cropper.y1, 0);
if (overflowX > 0 || overflowY > 0) {
this.cropper.x2 -= (overflowY * this.aspectRatio) > overflowX ? (overflowY * this.aspectRatio) : overflowX;
this.cropper.y1 += (overflowY * this.aspectRatio) > overflowX ? overflowY : overflowX / this.aspectRatio;
}
break;
case 'right':
case 'bottomright':
this.cropper.y2 = this.cropper.y1 + (this.cropper.x2 - this.cropper.x1) / this.aspectRatio;
overflowX = Math.max(this.cropper.x2 - this.maxSize.width, 0);
overflowY = Math.max(this.cropper.y2 - this.maxSize.height, 0);
if (overflowX > 0 || overflowY > 0) {
this.cropper.x2 -= (overflowY * this.aspectRatio) > overflowX ? (overflowY * this.aspectRatio) : overflowX;
this.cropper.y2 -= (overflowY * this.aspectRatio) > overflowX ? overflowY : overflowX / this.aspectRatio;
}
break;
case 'left':
case 'bottomleft':
this.cropper.y2 = this.cropper.y1 + (this.cropper.x2 - this.cropper.x1) / this.aspectRatio;
overflowX = Math.max(0 - this.cropper.x1, 0);
overflowY = Math.max(this.cropper.y2 - this.maxSize.height, 0);
if (overflowX > 0 || overflowY > 0) {
this.cropper.x1 += (overflowY * this.aspectRatio) > overflowX ? (overflowY * this.aspectRatio) : overflowX;
this.cropper.y2 -= (overflowY * this.aspectRatio) > overflowX ? overflowY : overflowX / this.aspectRatio;
}
break;
case 'center':
this.cropper.x2 = this.cropper.x1 + (this.cropper.y2 - this.cropper.y1) * this.aspectRatio;
this.cropper.y2 = this.cropper.y1 + (this.cropper.x2 - this.cropper.x1) / this.aspectRatio;
/** @type {?} */
var overflowX1 = Math.max(0 - this.cropper.x1, 0);
/** @type {?} */
var overflowX2 = Math.max(this.cropper.x2 - this.maxSize.width, 0);
/** @type {?} */
var overflowY1 = Math.max(this.cropper.y2 - this.maxSize.height, 0);
/** @type {?} */
var overflowY2 = Math.max(0 - this.cropper.y1, 0);
if (overflowX1 > 0 || overflowX2 > 0 || overflowY1 > 0 || overflowY2 > 0) {
this.cropper.x1 += (overflowY1 * this.aspectRatio) > overflowX1 ? (overflowY1 * this.aspectRatio) : overflowX1;
this.cropper.x2 -= (overflowY2 * this.aspectRatio) > overflowX2 ? (overflowY2 * this.aspectRatio) : overflowX2;
this.cropper.y1 += (overflowY2 * this.aspectRatio) > overflowX2 ? overflowY2 : overflowX2 / this.aspectRatio;
this.cropper.y2 -= (overflowY1 * this.aspectRatio) > overflowX1 ? overflowY1 : overflowX1 / this.aspectRatio;
}
break;
}
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.doAutoCrop = /**
* @private
* @return {?}
*/
function () {
if (this.autoCrop) {
this.crop();
}
};
/**
* @return {?}
*/
ImageCropperComponent.prototype.crop = /**
* @return {?}
*/
function () {
if (this.sourceImage && this.sourceImage.nativeElement && this.transformedImage != null) {
this.startCropImage.emit();
/** @type {?} */
var imagePosition = this.getImagePosition();
/** @type {?} */
var imgWidth = imagePosition.x2 - imagePosition.x1;
/** @type {?} */
var imgHeight = imagePosition.y2 - imagePosition.y1;
/** @type {?} */
var sourceImageElement = this.sourceImage.nativeElement;
/** @type {?} */
var ratio = this.transformedSize.width / sourceImageElement.offsetWidth;
/** @type {?} */
var scaledMaxWidthWithRatio = this.cropperScaledMaxWidth * ratio;
/** @type {?} */
var scaledMaxHeightWithRatio = this.cropperScaledMaxHeight * ratio;
/** @type {?} */
var width = imgWidth > scaledMaxWidthWithRatio ? scaledMaxHeightWithRatio : imgWidth;
/** @type {?} */
var height = imgHeight > scaledMaxHeightWithRatio ? scaledMaxHeightWithRatio : imgHeight;
/** @type {?} */
var cropCanvas = (/** @type {?} */ (document.createElement('canvas')));
cropCanvas.width = width;
cropCanvas.height = height;
/** @type {?} */
var ctx = cropCanvas.getContext('2d');
if (ctx) {
if (this.backgroundColor != null) {
ctx.fillStyle = this.backgroundColor;
ctx.fillRect(0, 0, width, height);
}
/** @type {?} */
var scaleX = (this.transform.scale || 1) * (this.transform.flipH ? -1 : 1);
/** @type {?} */
var scaleY = (this.transform.scale || 1) * (this.transform.flipV ? -1 : 1);
ctx.setTransform(scaleX, 0, 0, scaleY, this.transformedSize.width / 2, this.transformedSize.height / 2);
ctx.translate(-imagePosition.x1 / scaleX, -imagePosition.y1 / scaleY);
ctx.rotate((this.transform.rotate || 0) * Math.PI / 180);
ctx.drawImage(this.transformedImage, -this.transformedSize.width / 2, -this.transformedSize.height / 2);
/** @type {?} */
var output = {
width: width, height: height,
imagePosition: imagePosition,
cropperPosition: __assign({}, this.cropper)
};
if (this.containWithinAspectRatio) {
output.offsetImagePosition = this.getOffsetImagePosition();
}
/** @type {?} */
var resizeRatio = this.getResizeRatio(width, height);
if (resizeRatio !== 1) {
output.width = Math.round(width * resizeRatio);
output.height = this.maintainAspectRatio
? Math.round(output.width / this.aspectRatio)
: Math.round(height * resizeRatio);
resizeCanvas(cropCanvas, output.width, output.height);
}
output.base64 = this.cropToBase64(cropCanvas);
this.imageCropped.emit(output);
return output;
}
}
return null;
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.getImagePosition = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var sourceImageElement = this.sourceImage.nativeElement;
/** @type {?} */
var ratio = this.transformedSize.width / sourceImageElement.offsetWidth;
/** @type {?} */
var out = {
x1: Math.round(this.cropper.x1 * ratio),
y1: Math.round(this.cropper.y1 * ratio),
x2: Math.round(this.cropper.x2 * ratio),
y2: Math.round(this.cropper.y2 * ratio)
};
if (!this.containWithinAspectRatio) {
out.x1 = Math.max(out.x1, 0);
out.y1 = Math.max(out.y1, 0);
out.x2 = Math.min(out.x2, this.transformedSize.width);
out.y2 = Math.min(out.y2, this.transformedSize.height);
}
return out;
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.getOffsetImagePosition = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var canvasRotation = this.canvasRotation + this.exifTransform.rotate;
/** @type {?} */
var sourceImageElement = this.sourceImage.nativeElement;
/** @type {?} */
var ratio = this.transformedSize.width / sourceImageElement.offsetWidth;
/** @type {?} */
var offsetX;
/** @type {?} */
var offsetY;
if (canvasRotation % 2) {
offsetX = (this.transformedSize.width - this.originalSize.height) / 2;
offsetY = (this.transformedSize.height - this.originalSize.width) / 2;
}
else {
offsetX = (this.transformedSize.width - this.originalSize.width) / 2;
offsetY = (this.transformedSize.height - this.originalSize.height) / 2;
}
/** @type {?} */
var out = {
x1: Math.round(this.cropper.x1 * ratio) - offsetX,
y1: Math.round(this.cropper.y1 * ratio) - offsetY,
x2: Math.round(this.cropper.x2 * ratio) - offsetX,
y2: Math.round(this.cropper.y2 * ratio) - offsetY
};
if (!this.containWithinAspectRatio) {
out.x1 = Math.max(out.x1, 0);
out.y1 = Math.max(out.y1, 0);
out.x2 = Math.min(out.x2, this.transformedSize.width);
out.y2 = Math.min(out.y2, this.transformedSize.height);
}
return out;
};
/**
* @private
* @param {?} cropCanvas
* @return {?}
*/
ImageCropperComponent.prototype.cropToBase64 = /**
* @private
* @param {?} cropCanvas
* @return {?}
*/
function (cropCanvas) {
return cropCanvas.toDataURL('image/' + this.format, this.getQuality());
};
/**
* @private
* @return {?}
*/
ImageCropperComponent.prototype.getQuality = /**
* @private
* @return {?}
*/
function () {
return Math.min(1, Math.max(0, this.imageQuality / 100));
};
/**
* @param {?} width
* @param {?} height
* @return {?}
*/
ImageCropperComponent.prototype.getResizeRatio = /**
* @param {?} width
* @param {?} height
* @return {?}
*/
function (width, height) {
/** @type {?} */
var ratioWidth = this.resizeToWidth / width;
/** @type {?} */
var ratioHeight = this.resizeToHeight / height;
/** @type {?} */
var ratios = new Array();
if (this.resizeToWidth > 0) {
ratios.push(ratioWidth);
}
if (this.resizeToHeight > 0) {
ratios.push(ratioHeight);
}
/** @type {?} */
var result = ratios.length === 0 ? 1 : Math.min.apply(Math, __spread(ratios));
if (result > 1 && !this.onlyScaleDown) {
return result;
}
return Math.min(result, 1);
};
/**
* @private
* @param {?} event
* @return {?}
*/
ImageCropperComponent.prototype.getClientX = /**
* @private
* @param {?} event
* @return {?}
*/
function (event) {
return (event.touches && event.touches[0] ? event.touches[0].clientX : event.clientX) || 0;
};
/**
* @private
* @param {?} event
* @return {?}
*/
ImageCropperComponent.prototype.getClientY = /**
* @private
* @param {?} event
* @return {?}
*/
function (event) {
return (event.touches && event.touches[0] ? event.touches[0].clientY : event.clientY) || 0;
};
ImageCropperComponent.decorators = [
{ type: Component, args: [{
selector: 'image-cropper',
template: "<div [style.background]=\"imageVisible && backgroundColor\"\n #wrapper\n>\n <img\n #sourceImage\n class=\"source-image\"\n *ngIf=\"safeImgDataUrl\"\n [src]=\"safeImgDataUrl\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n [style.transform]=\"safeTransformStyle\"\n (load)=\"imageLoadedInView()\"\n />\n <div\n class=\"overlay\"\n [style.width.px]=\"maxSize.width\"\n [style.height.px]=\"maxSize.height\"\n [style.margin-left]=\"alignImage === 'center' ? marginLeft : null\"\n ></div>\n <div class=\"cropper\"\n *ngIf=\"imageVisible\"\n [class.rounded]=\"roundCropper\"\n [style.top.px]=\"cropper.y1\"\n [style.left.px]=\"cropper.x1\"\n [style.width.px]=\"cropper.x2 - cropper.x1\"\n [style.height.px]=\"cropper.y2 - cropper.y1\"\n [style.margin-left]=\"alignImage === 'center' ? marginLeft : null\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n (keydown)=\"keyboardAccess($event)\"\n tabindex=\"0\"\n >\n <div\n (mousedown)=\"startMove($event, moveTypes.Move)\"\n (touchstart)=\"startMove($event, moveTypes.Move)\"\n class=\"move\">\n </div>\n <ng-container *ngIf=\"!hideResizeSquares\">\n <span class=\"resize topleft\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topleft')\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize top\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize topright\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topright')\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize right\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize bottomright\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomright')\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize bottom\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize bottomleft\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomleft')\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize left\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize-bar top\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'top')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'top')\">\n </span>\n <span class=\"resize-bar right\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'right')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'right')\">\n </span>\n <span class=\"resize-bar bottom\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottom')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottom')\">\n </span>\n <span class=\"resize-bar left\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'left')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'left')\">\n </span>\n </ng-container>\n </div>\n</div>\n",
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [":host{display:flex;position:relative;width:100%;max-width:100%;max-height:100%;overflow:hidden;padding:5px;text-align:center}:host>div{width:100%;position:relative}:host>div img.source-image{max-width:100%;max-height:100%;transform-origin:center}:host .overlay{position:absolute;pointer-events:none;touch-action:none;outline:var(--cropper-overlay-color,#fff) solid 100vw;top:0;left:0}:host .cropper{position:absolute;display:flex;color:#53535c;background:0 0;outline:rgba(255,255,255,.3) solid 100vw;outline:var(--cropper-outline-color,rgba(255,255,255,.3)) solid 100vw;touch-action:none}:host .cropper:after{position:absolute;content:\"\";top:0;bottom:0;left:0;right:0;pointer-events:none;border:1px dashed;opacity:.75;color:inherit;z-index:1}:host .cropper .move{width:100%;cursor:move;border:1px solid rgba(255,255,255,.5)}:host .cropper:focus .move{border-color:#1e90ff;border-width:2px}:host .cropper .resize{position:absolute;display:inline-block;line-height:6px;padding:8px;opacity:.85;z-index:1}:host .cropper .resize .square{display:inline-block;background:#53535c;width:6px;height:6px;border:1px solid rgba(255,255,255,.5);box-sizing:content-box}:host .cropper .resize.topleft{top:-12px;left:-12px;cursor:nwse-resize}:host .cropper .resize.top{top:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .cropper .resize.topright{top:-12px;right:-12px;cursor:nesw-resize}:host .cropper .resize.right{top:calc(50% - 12px);right:-12px;cursor:ew-resize}:host .cropper .resize.bottomright{bottom:-12px;right:-12px;cursor:nwse-resize}:host .cropper .resize.bottom{bottom:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .cropper .resize.bottomleft{bottom:-12px;left:-12px;cursor:nesw-resize}:host .cropper .resize.left{top:calc(50% - 12px);left:-12px;cursor:ew-resize}:host .cropper .resize-bar{position:absolute;z-index:1}:host .cropper .resize-bar.top{top:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .cropper .resize-bar.right{top:11px;right:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .cropper .resize-bar.bottom{bottom:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .cropper .resize-bar.left{top:11px;left:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .cropper.rounded{outline-color:transparent}:host .cropper.rounded:after{border-radius:100%;box-shadow:0 0 0 100vw rgba(255,255,255,.3);box-shadow:0 0 0 100vw var(--cropper-outline-color,rgba(255,255,255,.3))}@media (orientation:portrait){:host .cropper{outline-width:100vh}:host .cropper.rounded:after{box-shadow:0 0 0 100vh rgba(255,255,255,.3);box-shadow:0 0 0 100vh var(--cropper-outline-color,rgba(255,255,255,.3))}}:host .cropper.rounded .move{border-radius:100%}:host.disabled .cropper .move,:host.disabled .cropper .resize,:host.disabled .cropper .resize-bar{display:none}"]
}] }
];
/** @nocollapse */
ImageCropperComponent.ctorParameters = function () { return [
{ type: DomSanitizer },
{ type: ChangeDetectorRef }
]; };
ImageCropperComponent.propDecorators = {
wrapper: [{ type: ViewChild, args: ['wrapper', { static: true },] }],
sourceImage: [{ type: ViewChild, args: ['sourceImage', { static: false },] }],
imageChangedEvent: [{ type: Input }],
imageURL: [{ type: Input }],
imageBase64: [{ type: Input }],
imageFile: [{ type: Input }],
format: [{ type: Input }],
maintainAspectRatio: [{ type: Input }],
transform: [{ type: Input }],
aspectRatio: [{ type: Input }],
resizeToWidth: [{ type: Input }],
resizeToHeight: [{ type: Input }],
cropperMinWidth: [{ type: Input }],
cropperMinHeight: [{ type: Input }],
cropperMaxHeight: [{ type: Input }],
cropperMaxWidth: [{ type: Input }],
cropperStaticWidth: [{ type: Input }],
cropperStaticHeight: [{ type: Input }],
canvasRotation: [{ type: Input }],
initialStepSize: [{ type: Input }],
roundCropper: [{ type: Input }],
onlyScaleDown: [{ type: Input }],
imageQuality: [{ type: Input }],
autoCrop: [{ type: Input }],
backgroundColor: [{ type: Input }],
containWithinAspectRatio: [{ type: Input }],
hideResizeSquares: [{ type: Input }],
cropper: [{ type: Input }],
alignImage: [{ type: HostBinding, args: ['style.text-align',] }, { type: Input }],
disabled: [{ type: HostBinding, args: ['class.disabled',] }, { type: Input }],
imageCropped: [{ type: Output }],
startCropImage: [{ type: Output }],
imageLoaded: [{ type: Output }],
cropperReady: [{ type: Output }],
loadImageFailed: [{ type: Output }],
onResize: [{ type: HostListener, args: ['window:resize',] }],
moveImg: [{ type: HostListener, args: ['document:mousemove', ['$event'],] }, { type: HostListener, args: ['document:touchmove', ['$event'],] }],
moveStop: [{ type: HostListener, args: ['document:mouseup',] }, { type: HostListener, args: ['document:touchend',] }]
};
return ImageCropperComponent;
}());
if (false) {
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.Hammer;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.originalImage;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.transformedImage;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.originalBase64;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.transformedBase64;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.moveStart;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.originalSize;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.transformedSize;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.setImageMaxSizeRetries;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.cropperScaledMinWidth;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.cropperScaledMinHeight;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.cropperScaledMaxWidth;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.cropperScaledMaxHeight;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.exifTransform;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.autoRotateSupported;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.stepSize;
/** @type {?} */
ImageCropperComponent.prototype.safeImgDataUrl;
/** @type {?} */
ImageCropperComponent.prototype.safeTransformStyle;
/** @type {?} */
ImageCropperComponent.prototype.marginLeft;
/** @type {?} */
ImageCropperComponent.prototype.maxSize;
/** @type {?} */
ImageCropperComponent.prototype.imageVisible;
/** @type {?} */
ImageCropperComponent.prototype.moveTypes;
/** @type {?} */
ImageCropperComponent.prototype.wrapper;
/** @type {?} */
ImageCropperComponent.prototype.sourceImage;
/** @type {?} */
ImageCropperComponent.prototype.imageChangedEvent;
/** @type {?} */
ImageCropperComponent.prototype.imageURL;
/** @type {?} */
ImageCropperComponent.prototype.imageBase64;
/** @type {?} */
ImageCropperComponent.prototype.imageFile;
/** @type {?} */
ImageCropperComponent.prototype.format;
/** @type {?} */
ImageCropperComponent.prototype.maintainAspectRatio;
/** @type {?} */
ImageCropperComponent.prototype.transform;
/** @type {?} */
ImageCropperComponent.prototype.aspectRatio;
/** @type {?} */
ImageCropperComponent.prototype.resizeToWidth;
/** @type {?} */
ImageCropperComponent.prototype.resizeToHeight;
/** @type {?} */
ImageCropperComponent.prototype.cropperMinWidth;
/** @type {?} */
ImageCropperComponent.prototype.cropperMinHeight;
/** @type {?} */
ImageCropperComponent.prototype.cropperMaxHeight;
/** @type {?} */
ImageCropperComponent.prototype.cropperMaxWidth;
/** @type {?} */
ImageCropperComponent.prototype.cropperStaticWidth;
/** @type {?} */
ImageCropperComponent.prototype.cropperStaticHeight;
/** @type {?} */
ImageCropperComponent.prototype.canvasRotation;
/** @type {?} */
ImageCropperComponent.prototype.initialStepSize;
/** @type {?} */
ImageCropperComponent.prototype.roundCropper;
/** @type {?} */
ImageCropperComponent.prototype.onlyScaleDown;
/** @type {?} */
ImageCropperComponent.prototype.imageQuality;
/** @type {?} */
ImageCropperComponent.prototype.autoCrop;
/** @type {?} */
ImageCropperComponent.prototype.backgroundColor;
/** @type {?} */
ImageCropperComponent.prototype.containWithinAspectRatio;
/** @type {?} */
ImageCropperComponent.prototype.hideResizeSquares;
/** @type {?} */
ImageCropperComponent.prototype.cropper;
/** @type {?} */
ImageCropperComponent.prototype.alignImage;
/** @type {?} */
ImageCropperComponent.prototype.disabled;
/** @type {?} */
ImageCropperComponent.prototype.imageCropped;
/** @type {?} */
ImageCropperComponent.prototype.startCropImage;
/** @type {?} */
ImageCropperComponent.prototype.imageLoaded;
/** @type {?} */
ImageCropperComponent.prototype.cropperReady;
/** @type {?} */
ImageCropperComponent.prototype.loadImageFailed;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.sanitizer;
/**
* @type {?}
* @private
*/
ImageCropperComponent.prototype.cd;
}
/**
* @fileoverview added by tsickle
* Generated from: lib/image-cropper.module.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var ImageCropperModule = /** @class */ (function () {
function ImageCropperModule() {
}
ImageCropperModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule
],
declarations: [
ImageCropperComponent
],
exports: [
ImageCropperComponent
]
},] }
];
return ImageCropperModule;
}());
/**
* @fileoverview added by tsickle
* Generated from: lib/interfaces/index.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* Generated from: lib/utils/blob.utils.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} base64Image
* @return {?}
*/
function base64ToFile(base64Image) {
/** @type {?} */
var split = base64Image.split(',');
/** @type {?} */
var type = split[0].replace('data:', '').replace(';base64', '');
/** @type {?} */
var byteString = atob(split[1]);
/** @type {?} */
var ab = new ArrayBuffer(byteString.length);
/** @type {?} */
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i += 1) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], { type: type });
}
/**
* @fileoverview added by tsickle
* Generated from: public-api.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* Generated from: ngx-image-cropper-upgraded.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { ImageCropperComponent, ImageCropperModule, base64ToFile };
//# sourceMappingURL=ngx-image-cropper-upgraded.js.map