image-resizer-cropper
Version:
A simple image crop with resizing built for Angular 7, compatible with Angular Universal (SSR).
566 lines (558 loc) • 24.3 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common')) :
typeof define === 'function' && define.amd ? define('image-resizer-cropper', ['exports', '@angular/core', '@angular/common'], factory) :
(factory((global['image-resizer-cropper'] = {}),global.ng.core,global.ng.common));
}(this, (function (exports,core,common) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var ImageResizerCropperComponent = /** @class */ (function () {
function ImageResizerCropperComponent(_el, _renderer, platformId) {
this._el = _el;
this._renderer = _renderer;
this.platformId = platformId;
this.croppedImage = new core.EventEmitter(null);
this.error = new core.EventEmitter(null);
this.isDown = false;
this.offSet = [];
this.isBrowser = common.isPlatformBrowser(this.platformId);
if (this.isBrowser) {
this.canvasOne = this._renderer.createElement("canvas");
this.contextOne = this.canvasOne.getContext("2d");
this.canvasTwo = this._renderer.createElement("canvas");
this.contextTwo = this.canvasTwo.getContext("2d");
this.canvasThree = this._renderer.createElement("canvas");
this.contextThree = this.canvasThree.getContext("2d");
this.canvasFour = this._renderer.createElement("canvas");
this.contextFour = this.canvasFour.getContext("2d");
this.imgOne = this._renderer.createElement("img");
this.imgTwo = this._renderer.createElement("img");
}
}
Object.defineProperty(ImageResizerCropperComponent.prototype, "crContainer", {
get: /**
* @return {?}
*/ function () {
return this._el.nativeElement.querySelector(".cr-container");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "crRange", {
get: /**
* @return {?}
*/ function () {
return this._el.nativeElement.querySelector("#cr-range");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "crImage", {
get: /**
* @return {?}
*/ function () {
return this._el.nativeElement.querySelector("#cr-image");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "crLens", {
get: /**
* @return {?}
*/ function () {
return this._el.nativeElement.querySelector("#cr-lens");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "btn", {
get: /**
* @return {?}
*/ function () {
return this._el.nativeElement.querySelector("#crop");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "testImg", {
get: /**
* @return {?}
*/ function () {
return this._el.nativeElement.querySelector("#test-img");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "finalCrop", {
get: /**
* @return {?}
*/ function () {
return this._el.nativeElement.querySelector("#final-crop");
},
enumerable: true,
configurable: true
});
Object.defineProperty(ImageResizerCropperComponent.prototype, "fileUpload", {
get: /**
* @return {?}
*/ function () {
return this._el.nativeElement.querySelector("#file-upload");
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
if (this.sourceImage) {
if (this.sourceImage.target && this.sourceImage.target.files) {
this.parseFile(this.sourceImage);
}
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
if (this.sourceImage) {
if (this.imgOne) {
this._renderer.setProperty(this.imgOne, "src", this.crImage.getAttribute("src"));
}
this.setUpListeners();
this.setUpConfigurations();
}
};
/**
* @param {?} changes
* @return {?}
*/
ImageResizerCropperComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
if (changes["sourceImage"] &&
!changes["sourceImage"].firstChange &&
changes["sourceImage"].currentValue) {
this.clearImagePosition();
if (changes["sourceImage"].currentValue.target &&
changes["sourceImage"].currentValue.target.files) {
this.parseFile(this.sourceImage);
}
else {
if (this.imgOne) {
this._renderer.setProperty(this.imgOne, "src", this.crImage.getAttribute("src"));
this.setUpListeners();
this.setUpConfigurations();
}
}
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.setUpListeners = /**
* @return {?}
*/
function () {
var _this = this;
if (this.isBrowser) {
this._renderer.listen(this.crRange, "input", function (event) {
_this.linkImageToRangeInput(event.target.value);
});
this._renderer.listen(this.crImage, "mousedown", function (event) {
_this.mouseDownOnImage(event);
});
this._renderer.listen(this.crImage, "mouseup", function (event) {
_this.mouseUpOnImage();
if (_this.autoCrop) {
_this.resizeAndCropImage();
}
});
this._renderer.listen(this.crImage, "mousemove", function (event) {
event.preventDefault();
_this.mouseMoveOnImage(event);
});
this._renderer.listen(this.crContainer, "mouseout", function (event) {
_this.keepMouseMoveInsideContainer();
});
this._renderer.listen(this.btn, "click", function (event) {
_this.resizeAndCropImage();
});
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.setUpConfigurations = /**
* @return {?}
*/
function () {
this.setBorderColor();
this.setBackgroundOpacity();
this.setLensHeightAndWidth();
};
/**
* @param {?} value
* @return {?}
*/
ImageResizerCropperComponent.prototype.linkImageToRangeInput = /**
* @param {?} value
* @return {?}
*/
function (value) {
/** @type {?} */
var val = value / 100;
this.crImage.style.transform = "scale(" + val + ")";
};
/**
* @param {?} event
* @return {?}
*/
ImageResizerCropperComponent.prototype.mouseDownOnImage = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.isDown = true;
this.offSet = [
event.target.offsetLeft - event.clientX,
event.target.offsetTop - event.clientY
];
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.mouseUpOnImage = /**
* @return {?}
*/
function () {
this.isDown = false;
};
/**
* @param {?} event
* @return {?}
*/
ImageResizerCropperComponent.prototype.mouseMoveOnImage = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (this.isDown) {
/** @type {?} */
var mousePosition = {
x: event.clientX,
y: event.clientY
};
this.crImage.style.left = mousePosition.x + this.offSet[0] + "px";
this.crImage.style.top = mousePosition.y + this.offSet[1] + "px";
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.keepMouseMoveInsideContainer = /**
* @return {?}
*/
function () {
this.isDown = false;
};
/**
* @param {?} e1
* @param {?} e2
* @return {?}
*/
ImageResizerCropperComponent.prototype.checkForOverlap = /**
* @param {?} e1
* @param {?} e2
* @return {?}
*/
function (e1, e2) {
if (e1.length && e1.length > 1) {
e1 = e1[0];
}
if (e2.length && e2.length > 1) {
e2 = e2[0];
}
/** @type {?} */
var rect1 = e1 instanceof Element ? e1.getBoundingClientRect() : false;
/** @type {?} */
var rect2 = e2 instanceof Element ? e2.getBoundingClientRect() : false;
/** @type {?} */
var overlap = null;
if (rect1 && rect2) {
overlap = !(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom);
return [overlap, rect1, rect2];
}
else {
return [overlap, rect1, rect2];
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.getResizeRatio = /**
* @return {?}
*/
function () {
/** @type {?} */
var transform = this.crImage.style.transform;
/** @type {?} */
var matrix = transform
.substring(transform.indexOf("(") + 1, transform.indexOf(")"))
.split(",");
return matrix.length > 0 ? matrix[0] : null;
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.drawImageResize = /**
* @return {?}
*/
function () {
/** @type {?} */
var ratio = this.getResizeRatio();
this.canvasTwo.width = this.imgOne.width;
this.canvasTwo.height = this.imgOne.height;
this.contextTwo.drawImage(this.imgOne, 0, 0);
this.canvasOne.width = this.imgOne.width * ratio;
this.canvasOne.height = this.imgOne.height * ratio;
this.contextOne.drawImage(this.canvasTwo, 0, 0, this.canvasTwo.width, this.canvasTwo.height, 0, 0, this.canvasOne.width, this.canvasOne.height);
/** @type {?} */
var i = this.canvasOne.toDataURL("image/png", 100);
if (this.testImg) {
this._renderer.setProperty(this.testImg, "src", i);
}
return i;
};
/**
* @param {?} src
* @return {?}
*/
ImageResizerCropperComponent.prototype.drawImageCrop = /**
* @param {?} src
* @return {?}
*/
function (src) {
var _this = this;
/** @type {?} */
var overlap = this.checkForOverlap(this.crLens, this.crImage);
if (this.imgTwo) {
this._renderer.setProperty(this.imgTwo, "src", src);
return new Promise(function (resolve, reject) {
_this._renderer.listen(_this.imgTwo, "load", function (event) {
_this.canvasThree.width = event.target.width;
_this.canvasThree.height = event.target.height;
_this.contextThree.drawImage(_this.imgTwo, 0, 0);
_this.canvasFour.width = _this.lensWidth;
_this.canvasFour.height = _this.lensHeight;
if (overlap) {
/** @type {?} */
var xCrop = overlap[1]["x"] - overlap[2]["x"];
/** @type {?} */
var yCrop = overlap[1]["y"] - overlap[2]["y"];
_this.contextFour.drawImage(_this.canvasThree, xCrop, yCrop, _this.lensWidth, _this.lensHeight, 0, 0, _this.lensWidth, _this.lensHeight);
if (_this.roundCrop) {
_this.contextFour.globalCompositeOperation = "destination-in";
_this.contextFour.beginPath();
_this.contextFour.arc(_this.lensWidth / 2, _this.lensHeight / 2, _this.lensHeight / 2, 0, Math.PI * 2);
_this.contextFour.closePath();
_this.contextFour.fill();
}
/** @type {?} */
var b_1 = _this.canvasFour.toDataURL("image/png", 100);
_this.cropAvailable = true;
setTimeout(function () {
if (_this.finalCrop) {
_this._renderer.setProperty(_this.finalCrop, "src", b_1);
}
});
resolve(b_1);
}
});
});
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.resizeAndCropImage = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var imgSrc = this.drawImageResize();
this.drawImageCrop(imgSrc).then(function (result) {
_this.croppedImage.emit(result);
console.log(result);
});
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.setLensHeightAndWidth = /**
* @return {?}
*/
function () {
if (this.lensHeight && this.lensHeight !== 150) {
this._renderer.setStyle(this.crLens, "height", this.lensHeight + "px");
}
if (this.lensWidth && this.lensWidth !== 150) {
this._renderer.setStyle(this.crLens, "width", this.lensWidth + "px");
}
if (this.roundCrop) {
this._renderer.addClass(this.crLens, "rounded");
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.setBorderColor = /**
* @return {?}
*/
function () {
var _this = this;
if (this.borderColor) {
this._renderer.setStyle(this.crContainer, "border-color", this.borderColor);
this._renderer.setStyle(this.crLens, "border-color", this.borderColor);
/** @type {?} */
var spans = this.crLens.querySelectorAll("span");
spans.forEach(function (element) {
_this._renderer.setStyle(element, "border-color", _this.borderColor);
});
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.setBackgroundOpacity = /**
* @return {?}
*/
function () {
if (this.backgroundOpacity && this.crLens) {
this._renderer.setStyle(this.crLens, "box-shadow", "0 0 0 200000px rgba(0, 0, 0, " + this.backgroundOpacity + ")");
}
};
/**
* @param {?} event
* @return {?}
*/
ImageResizerCropperComponent.prototype.parseFile = /**
* @param {?} event
* @return {?}
*/
function (event) {
var _this = this;
/** @type {?} */
var file = event.target.files[0];
if (file.type === "image/png" ||
file.type === "image/jpeg" ||
file.type === "image/gif" ||
file.type === "image/tiff") {
/** @type {?} */
var reader_1 = new FileReader();
reader_1.readAsDataURL(file);
reader_1.addEventListener("load", function (e) {
/** @type {?} */
var val = reader_1.result.toString();
_this._renderer.setProperty(_this.crImage, "src", val);
_this.loadedSourceImage = _this.crImage.getAttribute("src");
_this._renderer.setProperty(_this.imgOne, "src", _this.crImage.getAttribute("src"));
_this.setUpListeners();
_this.setUpConfigurations();
});
reader_1.onerror = function () {
console.log("there are some problems");
};
}
else {
this.loadedSourceImage = null;
if (this.crContainer) {
this._renderer.addClass(this.crContainer, "error");
}
this.errorMessage = "Invalid file type.";
this.error.emit(this.errorMessage);
}
};
/**
* @return {?}
*/
ImageResizerCropperComponent.prototype.clearImagePosition = /**
* @return {?}
*/
function () {
if (this.crImage) {
this.crImage.style.left = "auto";
this.crImage.style.top = "auto";
}
};
ImageResizerCropperComponent.decorators = [
{ type: core.Component, args: [{
selector: "irc-image-resizer-cropper",
template: "<ng-container *ngIf=\"sourceImage\">\n <div class=\"cr-container\">\n <div id=\"cr-lens\">\n <span></span>\n <span></span>\n <span></span>\n <span></span>\n </div>\n <img\n src=\"{{ loadedSourceImage }}\"\n style=\"transform: scale(1);\"\n draggable=\"false\"\n id=\"cr-image\"\n />\n <div *ngIf=\"errorMessage\" id=\"error-message\">{{ errorMessage }}</div>\n </div>\n <div class=\"cr-range-selector\">\n <input type=\"range\" id=\"cr-range\" min=\"10\" max=\"200\" />\n </div>\n <div class=\"text-center\">\n <button id=\"crop\" type=\"button\">Crop</button>\n </div>\n <div>\n <img src=\"#\" id=\"test-img\" style=\"display:none;\" />\n <img src=\"#\" *ngIf=\"previewCrop && cropAvailable\" id=\"final-crop\" />\n </div>\n</ng-container>\n",
styles: [".text-center{text-align:center}.cr-container{display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;position:relative;min-height:300px;margin:0 auto;overflow:hidden;border:2px dashed #333}.cr-range-selector{margin:1rem 0;text-align:center}#cr-lens{height:150px;width:150px;border:2px solid #333;z-index:999999;box-shadow:0 0 0 200000px rgba(0,0,0,.2);position:relative}#cr-lens.rounded{border-radius:50%}#cr-lens span{position:absolute;width:15px;height:15px}#cr-lens span:nth-child(1){top:-17px;left:-17px;border-right:2px dashed #333;border-bottom:2px dashed #333}#cr-lens span:nth-child(2){top:-17px;right:-17px;border-left:2px dashed #333;border-bottom:2px dashed #333}#cr-lens span:nth-child(3){bottom:-17px;right:-17px;border-left:2px dashed #333;border-top:2px dashed #333}#cr-lens span:nth-child(4){bottom:-17px;left:-17px;border-right:2px dashed #333;border-top:2px dashed #333}#cr-image{display:block;position:absolute;-webkit-transform-origin:center center;transform-origin:center center;cursor:move}"]
}] }
];
/** @nocollapse */
ImageResizerCropperComponent.ctorParameters = function () {
return [
{ type: core.ElementRef },
{ type: core.Renderer2 },
{ type: Object, decorators: [{ type: core.Inject, args: [core.PLATFORM_ID,] }] }
];
};
ImageResizerCropperComponent.propDecorators = {
sourceImage: [{ type: core.Input }],
lensHeight: [{ type: core.Input }],
lensWidth: [{ type: core.Input }],
autoCrop: [{ type: core.Input }],
previewCrop: [{ type: core.Input }],
roundCrop: [{ type: core.Input }],
borderColor: [{ type: core.Input }],
backgroundOpacity: [{ type: core.Input }],
croppedImage: [{ type: core.Output }],
error: [{ type: core.Output }]
};
return ImageResizerCropperComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var ImageResizerCropperModule = /** @class */ (function () {
function ImageResizerCropperModule() {
}
ImageResizerCropperModule.decorators = [
{ type: core.NgModule, args: [{
imports: [common.CommonModule],
declarations: [ImageResizerCropperComponent],
exports: [ImageResizerCropperComponent]
},] }
];
return ImageResizerCropperModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
exports.ImageResizerCropperComponent = ImageResizerCropperComponent;
exports.ImageResizerCropperModule = ImageResizerCropperModule;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=image-resizer-cropper.umd.js.map