ng-fancy-gui
Version:
This package contains components, for creating userinterfaces in a Angular app.
1,037 lines (1,024 loc) • 89.5 kB
JavaScript
import { __decorate } from 'tslib';
import { ɵɵdefineInjectable, Injectable, ElementRef, Input, ViewChild, HostListener, Component, forwardRef, EventEmitter, ChangeDetectorRef, Output, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { DomSanitizer } from '@angular/platform-browser';
import { HttpClient, HttpClientModule } from '@angular/common/http';
class ImageCropperConfig {
constructor(width, height, rasterLevels) {
this.width = width;
this.height = height;
this.rasterLevels = rasterLevels;
}
}
var AutCompleteSource;
(function (AutCompleteSource) {
AutCompleteSource[AutCompleteSource["Input"] = 0] = "Input";
AutCompleteSource[AutCompleteSource["ApiEndpoint"] = 1] = "ApiEndpoint";
})(AutCompleteSource || (AutCompleteSource = {}));
var KeywordType;
(function (KeywordType) {
KeywordType[KeywordType["String"] = 0] = "String";
KeywordType[KeywordType["KeyValue"] = 1] = "KeyValue";
})(KeywordType || (KeywordType = {}));
class KeywordPickerConfig {
constructor(keywordType = KeywordType.String, autocompleteMode = false, autoCompleteSource = AutCompleteSource.Input, dataMapperFunction = null, autocompleteSourceUrl = null) {
this.keywordType = keywordType;
this.autocompleteMode = autocompleteMode;
this.autoCompleteSource = autoCompleteSource;
this.dataMapperFunction = dataMapperFunction;
this.autocompleteSourceUrl = autocompleteSourceUrl;
}
}
var AutoCompleteSourceType;
(function (AutoCompleteSourceType) {
AutoCompleteSourceType[AutoCompleteSourceType["IdValueArray"] = 0] = "IdValueArray";
AutoCompleteSourceType[AutoCompleteSourceType["StringArray"] = 1] = "StringArray";
AutoCompleteSourceType[AutoCompleteSourceType["Object"] = 2] = "Object";
})(AutoCompleteSourceType || (AutoCompleteSourceType = {}));
let FileService = class FileService {
constructor() { }
getBase64(file) {
return new Promise(resolve => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = (error) => {
console.log('Error: ', error);
};
});
}
dataURLtoFile(dataurl, filename) {
const arr = dataurl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
getBinary(file) {
return new Promise(resolve => {
const reader = new FileReader();
reader.onloadend = () => {
const data = reader.result.split(',')[1];
const binaryBlob = atob(data);
resolve(binaryBlob);
};
reader.readAsDataURL(file);
});
}
};
FileService.ɵprov = ɵɵdefineInjectable({ factory: function FileService_Factory() { return new FileService(); }, token: FileService, providedIn: "root" });
FileService = __decorate([
Injectable({
providedIn: 'root'
})
], FileService);
var InputBetweenComponent_1;
let InputBetweenComponent = InputBetweenComponent_1 = class InputBetweenComponent {
constructor(elRef, sanitizer) {
this.elRef = elRef;
this.sanitizer = sanitizer;
this.placeholder = "";
this.max = 100;
this.min = 0;
this.lockScroll = true;
this.mouseDown = false;
this.minValue = 0;
this.maxValue = 0;
this.value = null;
this.maxTearMouseDown = false;
this.minTearMouseDown = false;
this.propagateChange = (_) => {
};
}
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched(fn) {
}
setDisabledState(isDisabled) {
}
writeValue(value) {
if (value !== null) {
this.minValue = Math.round(value[0]);
this.maxValue = Math.round(value[1]);
this.tearMinStyle = this.calcStyle(this.minValue);
this.tearMaxStyle = this.calcStyle(this.maxValue);
this.calcSliderLineStyle();
}
}
ngOnInit() {
if (this.value === null) {
this.minValue = Math.round(this.min + ((this.max - this.min) / 2));
this.maxValue = Math.round(this.min + ((this.max - this.min) / 2));
}
this.tearMinStyle = this.calcStyle(this.minValue);
this.tearMaxStyle = this.calcStyle(this.maxValue);
this.calcSliderLineStyle();
this.elRef.nativeElement.ontouchstart = () => {
this.disableScroll();
};
this.elRef.nativeElement.ontouchend = () => {
this.enableScroll();
};
}
resize() {
this.tearMinStyle = this.calcStyle(this.minValue);
this.tearMaxStyle = this.calcStyle(this.maxValue);
this.calcSliderLineStyle();
}
handleMouseLeave(event) {
const rect = this.elRef.nativeElement.getBoundingClientRect();
if (event.clientX >= rect.width + rect.x && this.maxTearMouseDown) {
this.maxValue = this.max;
}
if (event.clientX <= rect.x && this.minTearMouseDown) {
this.minValue = this.min;
}
this.maxTearMouseDown = false;
this.minTearMouseDown = false;
this.calcStyle(this.value);
this.tearMinStyle = this.calcStyle(this.minValue);
this.tearMaxStyle = this.calcStyle(this.maxValue);
this.calcSliderLineStyle();
}
handleTouchEnd(event) {
this.minTearMouseDown = false;
this.maxTearMouseDown = false;
this.calcStyle(this.value);
this.tearMinStyle = this.calcStyle(this.minValue);
this.tearMaxStyle = this.calcStyle(this.maxValue);
this.calcSliderLineStyle();
}
calcStyle(value) {
const unit = (this.elRef.nativeElement.clientWidth / (this.max - this.min));
return this.sanitizer.bypassSecurityTrustStyle('translate(' + ((Math.abs(this.min) * unit) + (unit * value)) + 'px, ' + -150 + '%) rotate(-135deg) translate(35%, -35%)');
}
calcSliderLineStyle() {
const unit = (this.elRef.nativeElement.clientWidth / (this.max - this.min));
this.sliderLineWidthStyle = this.sanitizer.bypassSecurityTrustStyle(unit * (this.maxValue - this.minValue) + 'px');
this.sliderLineLeftStyle = this.sanitizer.bypassSecurityTrustStyle((Math.abs(this.min) * unit) + (unit * this.minValue) + 'px');
}
disableScroll() {
document.body.style.overflowY = 'hidden';
}
enableScroll() {
document.body.style.overflowY = 'scroll';
}
tearMinDown() {
this.tearMin.nativeElement.classList.add('active');
this.minTearMouseDown = true;
}
tearMaxDown() {
this.tearMax.nativeElement.classList.add('active');
this.maxTearMouseDown = true;
}
processMouseEventTearMin(event) {
this.calcMinValue(event.clientX);
this.tearMinStyle = this.calcStyle(this.minValue);
this.calcSliderLineStyle();
}
processMouseEventTearMax(event) {
this.calcMaxValue(event.clientX);
this.tearMaxStyle = this.calcStyle(this.maxValue);
this.calcSliderLineStyle();
}
processMouseEvent(event) {
if (this.minTearMouseDown) {
this.processMouseEventTearMin(event);
}
if (this.maxTearMouseDown) {
this.processMouseEventTearMax(event);
}
}
processTouchEventTearMin(event) {
this.calcMinValue(event.touches[0].clientX);
this.tearMinStyle = this.calcStyle(this.minValue);
this.calcSliderLineStyle();
}
processTouchEventTearMax(event) {
this.calcMaxValue(event.touches[0].clientX);
this.tearMaxStyle = this.calcStyle(this.maxValue);
this.calcSliderLineStyle();
}
processTouchEvent(event) {
const rect = this.elRef.nativeElement.getBoundingClientRect();
if (this.minTearMouseDown) {
this.processTouchEventTearMin(event);
}
if (this.maxTearMouseDown) {
this.processTouchEventTearMax(event);
}
if (event.changedTouches[0].clientX >= rect.width + rect.x && this.maxTearMouseDown) {
this.maxValue = this.max;
// console.log("right leave");
this.tearMaxStyle = this.calcStyle(this.maxValue);
}
if (event.changedTouches[0].clientX <= rect.x && this.minTearMouseDown) {
//console.log("left leave");
this.minValue = this.min;
this.tearMinStyle = this.calcStyle(this.minValue);
}
}
calcMinValue(mouseX) {
const rect = this.elRef.nativeElement.getBoundingClientRect();
const x = mouseX - rect.left;
if (this.min + Math.round(((this.max - this.min) / (this.elRef.nativeElement.clientWidth)) * x) > this.min &&
this.min + Math.round(((this.max - this.min) / (this.elRef.nativeElement.clientWidth)) * x) < this.maxValue) {
this.minValue = this.min + Math.round(((this.max - this.min) / (this.elRef.nativeElement.clientWidth)) * x);
}
if (this.min + Math.round(((this.max - this.min) / (this.elRef.nativeElement.clientWidth)) * x) < this.min) {
this.minValue = this.min;
}
/*if (Math.round(((this.max - this.min) / (this.elRef.nativeElement.clientWidth)) * x) > this.maxValue) {
this.minValue = this.maxValue;
}*/
this.propagateChange([this.minValue, this.maxValue]);
}
calcMaxValue(mouseX) {
const rect = this.elRef.nativeElement.getBoundingClientRect();
const x = mouseX - rect.left;
if (this.min + Math.round(((this.max - this.min) / (this.elRef.nativeElement.clientWidth)) * x) > this.minValue &&
this.min + Math.round(((this.max - this.min) / (this.elRef.nativeElement.clientWidth)) * x) < this.max) {
this.maxValue = this.min + Math.round(((this.max - this.min) / (this.elRef.nativeElement.clientWidth)) * x);
}
/*if (Math.round(((this.max - this.min) / (this.elRef.nativeElement.clientWidth)) * x) < this.minValue) {
this.maxValue = this.minValue;
}*/
if (this.min + Math.round(((this.max - this.min) / (this.elRef.nativeElement.clientWidth)) * x) > this.max) {
this.maxValue = this.max;
}
this.propagateChange([this.minValue, this.maxValue]);
}
};
InputBetweenComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: DomSanitizer }
];
__decorate([
Input()
], InputBetweenComponent.prototype, "placeholder", void 0);
__decorate([
Input()
], InputBetweenComponent.prototype, "max", void 0);
__decorate([
Input()
], InputBetweenComponent.prototype, "min", void 0);
__decorate([
ViewChild('tearMax')
], InputBetweenComponent.prototype, "tearMax", void 0);
__decorate([
ViewChild('tearMin')
], InputBetweenComponent.prototype, "tearMin", void 0);
__decorate([
HostListener('window:resize')
], InputBetweenComponent.prototype, "resize", null);
InputBetweenComponent = InputBetweenComponent_1 = __decorate([
Component({
selector: 'fg-input-between',
template: "<div class=\"inputWrap noselect\"\n (touchmove)=\"processTouchEvent($event)\"\n (mousemove)=\"processMouseEvent($event)\"\n (mouseleave)=\"tearMin.classList.remove('active');tearMax.classList.remove('active');handleMouseLeave($event)\"\n (mouseup)=\"tearMax.classList.remove('active');maxTearMouseDown=false;tearMin.classList.remove('active');minTearMouseDown=false;\"\n (touchend)=\"tearMin.classList.remove('active');tearMax.classList.remove('active');handleTouchEnd($event)\"\n>\n <div class=\"fakeInputRange\">\n <div #tearMin class=\"tear\" [style.transform]=\"tearMinStyle\"\n [class.up]=\"minValue> 0 && maxValue===max\"\n (mousedown)=\"tearMinDown()\"\n (touchstart)=\"tearMinDown()\"\n >\n <span>{{minValue}}</span>\n </div>\n\n <div #tearMax class=\"tear\" [style.transform]=\"tearMaxStyle\"\n (mousedown)=\"tearMaxDown()\"\n (touchstart)=\"tearMaxDown()\"\n >\n <span>{{maxValue}}</span>\n </div>\n\n <div class=\"sliderLine\">\n <div class=\"sliderBackground\"></div>\n <div [style.width]=\"sliderLineWidthStyle\" [style.left]=\"sliderLineLeftStyle\" class=\"sliderActive\"></div>\n </div>\n </div>\n</div>\n\n\n\n",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputBetweenComponent_1),
multi: true
}
],
styles: [":host{display:block;position:relative}:host *{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.up{z-index:10}span{display:block;font-size:22px}.inputWrap{padding-top:32px}.inputWrap .fakeInputRange{position:relative}.inputWrap .fakeInputRange .tear{position:absolute;transition:width .5s,height .5s;width:30px;height:30px;border-radius:0 50% 50%;border:3px solid;transform:rotate(-135deg)}.inputWrap .fakeInputRange .tear span{color:#fff;transition:left .5s,top .5s,font-size .5s;font-size:9px;position:absolute;left:11px;top:11px;transform:translate(-50%,-50%) rotate(-225deg)}.inputWrap .fakeInputRange .tear.active{z-index:7;width:50px;height:50px}.inputWrap .fakeInputRange .tear.active span{font-size:19px;left:20px;top:20px}.sliderLine{margin-top:20px;position:relative}.sliderLine .sliderBackground{width:100%;height:2px;background-color:gray}.sliderLine .sliderActive{position:absolute;height:2px;top:0;left:0}input{opacity:0;top:0;left:0;z-index:1;position:absolute;margin-top:7px;height:100%;font-size:21px;border:1px solid}input.invalid{border:1px solid}"]
})
], InputBetweenComponent);
class CropImage {
constructor(imageCroper, x, y, src) {
this.imageCroper = imageCroper;
this.x = x;
this.y = y;
this.src = src;
this.loaded = false;
this.rotation = 0;
this.userInputRotation = 0;
this.locked = false;
this.minWidth = 0;
this.minHeight = 0;
this.repositioningSpeed = 1;
this.moveing = false;
this.orignalImage = new Image();
this.orignalImage.src = src;
this.orignalImage.onload = () => {
const fc = document.createElement('canvas');
const fctx = fc.getContext("2d");
const oc = document.createElement('canvas');
const octx = oc.getContext('2d');
//document.body.append(oc);
//document.body.append(fc);
if (this.orignalImage.width > this.orignalImage.height) {
fc.width = (this.orignalImage.width / this.orignalImage.height) * this.imageCroper.config.height;
fc.height = this.imageCroper.config.height;
}
else {
fc.width = this.imageCroper.config.width;
fc.height = (this.orignalImage.height / this.orignalImage.width) * this.imageCroper.config.width;
}
const steps = Math.ceil(Math.log(this.orignalImage.width / this.imageCroper.config.width) / Math.log(2));
//console.log(fc);
// console.log(this.orignalImage.width, this.orignalImage.height);
oc.width = this.orignalImage.width * 0.5;
oc.height = this.orignalImage.height * 0.5;
octx.drawImage(this.orignalImage, 0, 0, oc.width, oc.height);
let factor = 1;
for (let i = 0; i < steps - 3; i++) {
octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);
factor *= 0.5;
}
fctx.drawImage(oc, 0, 0, oc.width * factor, oc.height * factor, 0, 0, fctx.canvas.width, fctx.canvas.height);
this.image = new Image();
this.image.src = fc.toDataURL();
this.image.onload = () => {
console.log(this.image.width);
this.originalWidth = this.image.width;
this.originalHeight = this.image.height;
this.width = this.originalWidth;
this.height = this.originalHeight;
this.coverCanvas();
this.loaded = true;
};
};
}
setMinSize() {
if (this.userInputRotation === 0) {
switch (this.rotation) {
case 0: {
if (this.originalWidth >= this.originalHeight) {
this.setMinSizeByWidth(this.imageCroper.canvas.width);
}
if (this.originalHeight >= this.originalWidth) {
this.setMinSizeByHeight(this.imageCroper.canvas.height);
}
break;
}
case -90: {
if (this.originalWidth >= this.originalHeight) {
this.setMinSizeByHeight(this.imageCroper.canvas.width);
}
if (this.originalHeight >= this.originalWidth) {
this.setMinSizeByWidth(this.imageCroper.canvas.height);
}
break;
}
case -180: {
if (this.originalWidth >= this.originalHeight) {
this.setMinSizeByWidth(this.imageCroper.canvas.width);
}
if (this.originalHeight >= this.originalWidth) {
this.setMinSizeByHeight(this.imageCroper.canvas.height);
}
break;
}
case -270: {
if (this.originalWidth >= this.originalHeight) {
this.setMinSizeByHeight(this.imageCroper.canvas.width);
}
if (this.originalHeight >= this.originalWidth) {
this.setMinSizeByWidth(this.imageCroper.canvas.height);
}
break;
}
}
if (this.minWidth < this.imageCroper.canvas.width || this.minHeight < this.imageCroper.canvas.height) {
if (this.rotation === 0 || this.rotation === -180) {
if (this.imageCroper.canvas.width > this.imageCroper.canvas.height) {
this.setMinSizeByWidth(this.imageCroper.canvas.width);
}
else {
this.setMinSizeByHeight(this.imageCroper.canvas.height);
}
}
else {
if (this.imageCroper.canvas.width > this.imageCroper.canvas.height) {
this.setMinSizeByHeight(this.imageCroper.canvas.width);
}
else {
this.setMinSizeByWidth(this.imageCroper.canvas.height);
}
}
}
}
}
drawImageToCanvas(ctx = this.imageCroper.ctx) {
const x = (this.x / this.imageCroper.canvas.width) * ctx.canvas.width;
const y = (this.y / this.imageCroper.canvas.height) * ctx.canvas.height;
const width = (this.width / this.imageCroper.canvas.width) * ctx.canvas.width;
const height = (this.height / this.imageCroper.canvas.height) * ctx.canvas.height;
ctx.beginPath();
ctx.translate(x, y);
ctx.rotate((Math.PI / 180) * (this.rotation + this.userInputRotation));
ctx.imageSmoothingEnabled = false;
ctx.drawImage(this.orignalImage, -width * 0.5, -height * 0.5, width, height);
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.closePath();
}
render() {
if (this.loaded) {
this.drawImageToCanvas();
}
}
resize(factor) {
const verhaeltinis = this.originalHeight / this.originalWidth;
this.width = this.width * factor;
this.height = verhaeltinis * this.width;
this.coverCanvas();
}
coverCanvas() {
let overLeftBorder = false;
let overRightBorder = false;
let overTopBorder = false;
let overBottomBorder = false;
this.setMinSize();
if (this.minHeight > this.height || this.minWidth > this.width) {
this.width = this.minWidth;
this.height = this.minHeight;
// console.log(`set min size ${this.width} ${this.height}`);
}
if (this.rotation === 0 || this.rotation === -180) {
if (this.x - (this.width / 2) > 0) { // over left border
this.x = (this.width / 2);
overLeftBorder = true;
}
if (this.x + (this.width / 2) < this.imageCroper.canvas.width) { // over right border
this.x = this.imageCroper.canvas.width - (this.width / 2);
overRightBorder = true;
}
if (this.y - (this.height / 2) > 0) { // over top
this.y = (this.height / 2);
overTopBorder = true;
}
if (this.y + (this.height / 2) < this.imageCroper.canvas.height) { // bottom border
this.y = this.imageCroper.canvas.height - (this.height / 2);
overBottomBorder = true;
}
if (this.originalWidth < this.originalHeight) {
if (overLeftBorder && overRightBorder) {
this.x = (this.imageCroper.canvas.width / 2);
this.resizeByWidth(this.imageCroper.canvas.width);
if (overTopBorder) {
this.y = (this.height / 2);
}
if (overBottomBorder) {
this.y = this.imageCroper.canvas.height - (this.height / 2);
}
}
}
else {
if (overTopBorder && overBottomBorder) {
this.y = (this.imageCroper.canvas.height / 2);
this.resizeByHeight(this.imageCroper.canvas.height);
if (overLeftBorder) {
this.x = (this.width / 2);
}
if (overRightBorder) {
this.x = this.imageCroper.canvas.width - (this.width / 2);
}
}
}
}
else if (this.rotation === -90 || this.rotation === -270) {
if (this.x - (this.height / 2) > 0) { // over left border
this.x = (this.height / 2);
overLeftBorder = true;
}
if (this.x + (this.height / 2) < this.imageCroper.canvas.width) { // over right border
this.x = this.imageCroper.canvas.width - (this.height / 2);
overRightBorder = true;
}
if (this.y - (this.width / 2) > 0) { // over top
this.y = (this.width / 2);
overTopBorder = true;
}
if (this.y + (this.width / 2) < this.imageCroper.canvas.height) { // bottom border
this.y = this.imageCroper.canvas.height - (this.width / 2);
overBottomBorder = true;
}
if (this.originalWidth > this.originalHeight) {
if (overTopBorder && overBottomBorder) {
this.y = (this.imageCroper.canvas.height / 2);
this.resizeByWidth(this.imageCroper.canvas.height);
if (overLeftBorder) {
this.x = (this.height / 2);
}
if (overRightBorder) {
this.x = this.imageCroper.canvas.width - (this.height / 2);
}
}
}
else {
if (overLeftBorder && overRightBorder) {
this.x = (this.imageCroper.canvas.width / 2);
this.resizeByHeight(this.imageCroper.canvas.width);
if (overTopBorder) {
this.y = (this.width / 2);
}
if (overBottomBorder) {
this.y = this.imageCroper.canvas.height - (this.width / 2);
}
}
}
}
// console.log("cover");
}
resizeOriginalImage(factor) {
const verhaeltinis = this.originalHeight / this.originalWidth;
this.width = this.originalWidth * factor;
this.height = verhaeltinis * this.width;
}
resetOriginalImage() {
this.originalWidth = this.width;
this.originalHeight = this.height;
}
resizeByDeltaHeight(delataHeight) {
const verhaeltinis = this.originalWidth / this.originalHeight;
this.height += delataHeight;
this.width = this.height * verhaeltinis;
}
resizeByDeltaWidth(delataWidth) {
const verhaeltinis = this.originalHeight / this.originalWidth;
this.width += delataWidth;
this.height = verhaeltinis * this.width;
}
resizeByWidth(width) {
const verhaeltinis = this.originalHeight / this.originalWidth;
this.width = width;
this.height = verhaeltinis * width;
}
resizeByHeight(height) {
const verhaeltinis = this.originalWidth / this.originalHeight;
this.height = height;
this.width = verhaeltinis * this.height;
}
setUserInputRotation(deg) {
this.userInputRotation = deg;
this.setMinSize();
}
setMinSizeByWidth(newWidth) {
//console.log("set new witdh: ", newWidth);
const heightWidthRatio = this.originalHeight / this.originalWidth;
this.minWidth = newWidth;
this.minHeight = heightWidthRatio * this.minWidth;
}
setMinSizeByHeight(newHeight) {
//console.log("set new height : ", newHeight);
const widthHeightRatio = this.originalWidth / this.originalHeight;
this.minHeight = newHeight;
this.minWidth = widthHeightRatio * this.minHeight;
}
}
class GestureHandler {
constructor(imageCroper) {
this.imageCroper = imageCroper;
this.imageCroper.canvas.onmousemove = (evt) => {
this.handleMove(evt);
};
this.imageCroper.canvas.ontouchmove = (evt) => {
evt.preventDefault();
this.handleTouch(evt);
};
this.imageCroper.canvas.onwheel = (evt) => {
event.preventDefault();
if (evt.deltaY < 0) {
this.imageCroper.cropImage.resize(1.1);
}
else {
if (!this.imageCroper.cropImage.locked) {
this.imageCroper.cropImage.resize(0.9);
}
}
};
}
handleMove(evt) {
//console.log("move");
const halfImageWidth = this.imageCroper.cropImage.width * 0.5;
const halfImageHeight = this.imageCroper.cropImage.height * 0.5;
const newImageX = this.imageCroper.cropImage.x + this.imageCroper.mouse.x - this.imageCroper.mouse.lastX;
const newImageY = this.imageCroper.cropImage.y + this.imageCroper.mouse.y - this.imageCroper.mouse.lastY;
const mouseXdiff = this.imageCroper.mouse.x - this.imageCroper.mouse.lastX;
const mouseYdiff = this.imageCroper.mouse.y - this.imageCroper.mouse.lastY;
if (this.imageCroper.mouse.isDown && !this.imageCroper.cropImage.locked) {
if ((this.imageCroper.cropImage.rotation === 0 || this.imageCroper.cropImage.rotation === -180) &&
this.imageCroper.cropImage.userInputRotation === 0) { // with, height is default
if ((newImageX - halfImageWidth <= 0 && newImageX + halfImageWidth >= this.imageCroper.canvas.width) ||
this.imageCroper.cropImage.userInputRotation !== 0) {
this.imageCroper.cropImage.x += mouseXdiff;
}
if ((newImageY + halfImageHeight >= this.imageCroper.canvas.height && newImageY - halfImageHeight <= 0) ||
this.imageCroper.cropImage.userInputRotation !== 0) {
this.imageCroper.cropImage.y += mouseYdiff;
}
}
else { // with, height is switched
if ((newImageX - halfImageHeight <= 0 && newImageX + halfImageHeight >= this.imageCroper.canvas.width) ||
this.imageCroper.cropImage.userInputRotation !== 0) {
this.imageCroper.cropImage.x += mouseXdiff;
}
if ((newImageY + halfImageWidth >= this.imageCroper.canvas.height && (newImageY - halfImageWidth) <= 0) ||
this.imageCroper.cropImage.userInputRotation !== 0) {
this.imageCroper.cropImage.y += mouseYdiff;
}
}
}
this.imageCroper.mouse.syncPosition(evt);
}
handleTouch(evt) {
const halfImageWidth = this.imageCroper.cropImage.width * 0.5;
const halfImageHeight = this.imageCroper.cropImage.height * 0.5;
const newImageX = this.imageCroper.cropImage.x + this.imageCroper.mouse.x - this.imageCroper.mouse.lastX;
const newImageY = this.imageCroper.cropImage.y + this.imageCroper.mouse.y - this.imageCroper.mouse.lastY;
const mouseXdiff = this.imageCroper.mouse.x - this.imageCroper.mouse.lastX;
const mouseYdiff = this.imageCroper.mouse.y - this.imageCroper.mouse.lastY;
if (this.imageCroper.mouse.isDown && !this.imageCroper.cropImage.locked) {
if ((this.imageCroper.cropImage.rotation === 0 || this.imageCroper.cropImage.rotation === -180) &&
this.imageCroper.cropImage.userInputRotation === 0) { // with, height is default
if ((newImageX - halfImageWidth <= 0 && newImageX + halfImageWidth >= this.imageCroper.canvas.width) ||
this.imageCroper.cropImage.userInputRotation !== 0) {
this.imageCroper.cropImage.x += mouseXdiff;
}
if ((newImageY + halfImageHeight >= this.imageCroper.canvas.height && newImageY - halfImageHeight <= 0) ||
this.imageCroper.cropImage.userInputRotation !== 0) {
this.imageCroper.cropImage.y += mouseYdiff;
}
}
else { // with, height is switched
if ((newImageX - halfImageHeight <= 0 && newImageX + halfImageHeight >= this.imageCroper.canvas.width) ||
this.imageCroper.cropImage.userInputRotation !== 0) {
this.imageCroper.cropImage.x += mouseXdiff;
}
if ((newImageY + halfImageWidth >= this.imageCroper.canvas.height && (newImageY - halfImageWidth) <= 0) ||
this.imageCroper.cropImage.userInputRotation !== 0) {
this.imageCroper.cropImage.y += mouseYdiff;
}
}
}
this.imageCroper.mouse.syncTouchPosition(evt);
}
}
class Mouse {
constructor(imageCroper) {
this.imageCroper = imageCroper;
this.pinching = false;
this.lastX = 0;
this.lastY = 0;
this.isDown = false;
this.imageCroper.canvas.style.cursor = 'grab';
this.imageCroper.canvas.onmousedown = (evt) => {
this.imageCroper.canvas.style.cursor = 'grabbing';
this.syncPosition(evt);
this.lastY = this.y;
this.lastX = this.x;
this.isDown = true;
this.imageCroper.cropImage.moveing = true;
};
this.imageCroper.canvas.onmouseup = () => {
this.imageCroper.canvas.style.cursor = 'grab';
this.isDown = false;
};
this.imageCroper.canvas.ontouchstart = (evt) => {
this.imageCroper.canvas.style.cursor = 'grabbing';
this.syncTouchPosition(evt);
this.lastY = this.y;
this.lastX = this.x;
this.isDown = true;
this.imageCroper.cropImage.moveing = true;
};
this.imageCroper.canvas.ontouchend = () => {
this.imageCroper.canvas.style.cursor = 'grab';
this.isDown = false;
};
}
syncPosition(evt) {
const rect = this.imageCroper.canvas.getBoundingClientRect();
this.lastX = this.x;
this.lastY = this.y;
this.x = evt.clientX - rect.left;
this.y = ((evt.clientY - rect.top));
}
syncTouchPosition(evt) {
const rect = this.imageCroper.canvas.getBoundingClientRect();
this.lastX = this.x;
this.lastY = this.y;
this.x = evt.touches[0].clientX - rect.left;
this.y = ((evt.touches[0].clientY - rect.top));
}
}
class ImageCroper {
constructor(canvas, offscreenCanvas, width, height, imageSrc, config) {
this.canvas = canvas;
this.offscreenCanvas = offscreenCanvas;
this.width = width;
this.height = height;
this.config = config;
this.raster = false;
this.rasterLevelIndex = 0;
this.ctx = this.setupCanvas(this.canvas);
this.offscreenCtx = this.setupCanvas(this.offscreenCanvas);
this.canvas.width = config.width;
this.canvas.height = config.height;
this.offscreenCanvas.width = config.width;
this.offscreenCanvas.height = config.height;
this.imageHeightWidthRatio = this.config.height / this.config.width;
this.imageWidthHeightRatio = this.config.width / this.config.height;
this.setCanvasSize();
this.cropImage = new CropImage(this, this.canvas.width / 2, this.canvas.height / 2, imageSrc);
this.gestureHandler = new GestureHandler(this);
this.mouse = new Mouse(this);
this.cropImage.coverCanvas();
}
resize() {
//console.log("resize imagecropper");
const toSmall = this.setCanvasSize();
this.cropImage.coverCanvas();
return toSmall;
}
clear() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
render() {
this.clear();
this.cropImage.render();
if (this.raster) {
let strecke = this.canvas.height / this.config.rasterLevels[this.rasterLevelIndex];
let streckeT = 0;
for (let i = 0; i <= this.config.rasterLevels[this.rasterLevelIndex]; i++) {
this.ctx.beginPath();
this.ctx.moveTo(0, streckeT);
this.ctx.lineTo(this.canvas.width, streckeT);
this.ctx.strokeStyle = 'white';
this.ctx.stroke();
this.ctx.closePath();
streckeT += strecke;
}
strecke = this.canvas.width / this.config.rasterLevels[this.rasterLevelIndex];
streckeT = 0;
for (let i = 0; i <= this.config.rasterLevels[this.rasterLevelIndex]; i++) {
this.ctx.beginPath();
this.ctx.moveTo(streckeT, 0);
this.ctx.lineTo(streckeT, this.canvas.height);
this.ctx.strokeStyle = 'white';
this.ctx.stroke();
this.ctx.closePath();
streckeT += strecke;
}
}
}
rotateImage(deg) {
this.cropImage.rotation = deg;
}
switchRasterLevelIndex() {
if (this.raster) {
if (this.rasterLevelIndex + 1 < this.config.rasterLevels.length) {
this.rasterLevelIndex++;
}
else {
this.raster = false;
}
}
else {
this.rasterLevelIndex = 0;
this.raster = true;
}
}
setupCanvas(canvas) {
// Get the device pixel ratio, falling back to 1.
const dpr = window.devicePixelRatio || 1;
// Get the size of the canvas in CSS pixels.
const rect = canvas.getBoundingClientRect();
// Give the canvas pixel dimensions of their CSS
// size * the device pixel ratio.
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
const ctx = canvas.getContext('2d');
// Scale all drawing operations by the dpr, so you
// don't have to worry about the difference.
ctx.scale(dpr, dpr);
return ctx;
}
setCanvasSize() {
this.canvas.width = this.canvas.parentElement.clientWidth;
this.canvas.height = this.canvas.width * this.imageHeightWidthRatio;
this.offscreenCanvas.width = this.width;
this.offscreenCanvas.height = this.height;
const reducedCanvasHeight = (this.canvas.parentElement.parentElement.clientHeight - 350);
if (reducedCanvasHeight < 0) {
return true;
}
if (this.canvas.height > reducedCanvasHeight && this.canvas.width < this.config.width && this.canvas.height < this.config.height) {
this.canvas.height = reducedCanvasHeight;
this.canvas.width = this.canvas.height * this.imageWidthHeightRatio;
}
else {
this.canvas.width = this.config.width;
this.canvas.height = this.config.height;
}
return false;
}
}
let ImageCropperComponent = class ImageCropperComponent {
constructor(cdRef) {
this.cdRef = cdRef;
this.imageSrc = null;
this.config = null;
this.continue = new EventEmitter();
this.cancle = new EventEmitter();
this.toSmall = false;
this.animationFrameHandler = null;
}
ngAfterViewInit() {
if (this.imageSrc === null) {
throw new Error("Ng Fancy GUI: No imagesrc was passed in to the imagecropper component");
}
if (this.config === null) {
this.config = new ImageCropperConfig(500, 500, [4, 8, 16]);
}
if (this.config instanceof ImageCropperConfig) {
this.imageCroper = new ImageCroper(this.cropperCanvas.nativeElement, this.offscreenCanvas.nativeElement, this.config.width, this.config.height, this.imageSrc, this.config);
console.log("immageCropper:", this.imageCroper);
this.startLoop();
this.resize();
this.cdRef.detectChanges();
}
else {
throw new Error("Ng Fancy GUI: Config passed in to imagecropper was not of type ImageCropperConfig");
}
}
zoom(x) {
if (x > 0) {
this.imageCroper.cropImage.resize(1.01);
}
else if (x < 0) {
this.imageCroper.cropImage.resize(0.99);
}
}
startLoop() {
const step = () => {
this.imageCroper.render();
this.animationFrameHandler = window.requestAnimationFrame(step);
//console.log("render");
};
this.animationFrameHandler = window.requestAnimationFrame(step);
}
resize() {
this.toSmall = this.imageCroper.resize();
}
ngOnDestroy() {
window.cancelAnimationFrame(this.animationFrameHandler);
//console.log("destroy");
}
pinch(event) {
this.pinchEvent = event;
this.imageCroper.cropImage.resizeOriginalImage(event.scale);
}
pinchEnd() {
this.imageCroper.cropImage.resetOriginalImage();
}
toggleRaster() {
this.imageCroper.switchRasterLevelIndex();
}
rotate90Deg() {
this.imageCroper.cropImage.rotation -= 90;
if (this.imageCroper.cropImage.rotation === -360) {
this.imageCroper.cropImage.rotation = 0;
}
//console.log(this.imageCroper.cropImage.rotation);
this.imageCroper.cropImage.coverCanvas();
}
cancleE() {
this.cancle.emit();
}
continueE() {
this.imageCroper.cropImage.drawImageToCanvas(this.imageCroper.offscreenCtx);
this.continue.emit(this.imageCroper.offscreenCtx.canvas.toDataURL());
}
};
ImageCropperComponent.ctorParameters = () => [
{ type: ChangeDetectorRef }
];
__decorate([
ViewChild('cropperCanvas')
], ImageCropperComponent.prototype, "cropperCanvas", void 0);
__decorate([
ViewChild('offscreenCanvas')
], ImageCropperComponent.prototype, "offscreenCanvas", void 0);
__decorate([
Input()
], ImageCropperComponent.prototype, "imageSrc", void 0);
__decorate([
Input()
], ImageCropperComponent.prototype, "config", void 0);
__decorate([
Output()
], ImageCropperComponent.prototype, "continue", void 0);
__decorate([
Output()
], ImageCropperComponent.prototype, "cancle", void 0);
__decorate([
HostListener('window:resize')
], ImageCropperComponent.prototype, "resize", null);
ImageCropperComponent = __decorate([
Component({
selector: 'fg-image-cropper',
template: "<ng-container [class.hidden]=\"imageCroper && imageCroper.cropImage.loaded\">\n <div [class.hidden]=\"!toSmall\" class=\"tosmallOverlay\">\n <div>\n <div>\n <h2>Screen is to small</h2>\n </div>\n <div (click)=\"cancleE()\">\n cancle\n </div>\n </div>\n </div>\n <div class=\"topSection\">\n <div class=\"inner\">\n <h2>Crop Your Image</h2>\n <button (click)=\"rotate90Deg()\" class=\"right\" type=\"button\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path\n d=\"M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z\" />\n </svg>\n </button>\n\n <button type=\"button\" (click)=\"toggleRaster()\" class=\"left\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"300\" height=\"300\" viewBox=\"0 0 300 300\">\n <g id=\"Gruppe_48\" data-name=\"Gruppe 48\" transform=\"translate(-467.5 -968.5)\">\n <g id=\"Gruppe_47\" data-name=\"Gruppe 47\" transform=\"translate(3 443)\">\n <line id=\"Linie_3\" data-name=\"Linie 3\" y2=\"300\" transform=\"translate(559.5 525.5)\" fill=\"none\"\n stroke=\"#000\" stroke-width=\"20\" />\n <line id=\"Linie_4\" data-name=\"Linie 4\" y2=\"300\" transform=\"translate(669.5 525.5)\" fill=\"none\"\n stroke=\"#000\" stroke-width=\"20\" />\n </g>\n <g id=\"Gruppe_46\" data-name=\"Gruppe 46\" transform=\"translate(135 416)\">\n <line id=\"Linie_5\" data-name=\"Linie 5\" x2=\"300\" transform=\"translate(332.5 647.5)\" fill=\"none\"\n stroke=\"#000\" stroke-width=\"20\" />\n <line id=\"Linie_6\" data-name=\"Linie 6\" x2=\"300\" transform=\"translate(332.5 757.5)\" fill=\"none\"\n stroke=\"#000\" stroke-width=\"20\" />\n </g>\n </g>\n </svg>\n </button>\n </div>\n </div>\n <div class=\"canvasWrap\">\n <canvas #cropperCanvas></canvas>\n <canvas #offscreenCanvas style=\"display: none\"></canvas>\n </div>\n <div class=\"container\">\n <fg-slider-infinite (change)=\"zoom($event)\"></fg-slider-infinite>\n <div class=\"buttonWrapp\">\n <button (click)=\"continueE()\" class=\"btn\" type=\"button\">Continue</button>\n <button (click)=\"cancleE()\" class=\"btn\" type=\"button\">Cancle</button>\n </div>\n </div>\n</ng-container>",
styles: [".buttonWrapp{display:flex;justify-content:space-between}:host{overflow:hidden;display:block}:host *{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.hidden{display:none!important}.tosmallOverlay{text-align:center;width:100%;height:100%;background-color:rgba(0,0,0,.767);color:#fff;display:flex;justify-content:center;align-items:center}canvas{border:1px solid #000}fg-slider-infinite{margin-top:10px;display:block}button{touch-action:none;margin-top:10px}.btn{color:#fff;flex-basis:48%;font-size:20px;border:none;height:50px;padding:9px auto}.canvasWrap{text-align:center;max-width:1000px;margin:0 auto}.topSection{border-bottom:1px solid gray;position:relative;text-align:center}.topSection .inner{margin:0 auto;width:100%;max-width:500px;height:100%;position:relative}.topSection .inner h2{display:inline-block;padding-top:10px;padding-bottom:10px}.topSection .inner button{background-color:transparent;border:none;outline:0;margin-top:0;height:100%;width:52px;position:absolute}.topSection .inner button.left{left:0}.topSection .inner button.right{right:0}.topSection .inner button svg{margin-top:5px;width:30px;height:auto}.topSection .inner button:hover{opacity:.75}.container{max-width:1000px;padding:0 20px;margin:0 auto}"]
})
], ImageCropperComponent);
var InputImageComponent_1;
let InputImageComponent = InputImageComponent_1 = class InputImageComponent {
constructor(host, fileService, sanitizer) {
this.host = host;
this.fileService = fileService;
this.sanitizer = sanitizer;
this.invalid = false;
this.width = 500;
this.height = 500;
this.value = null;
this.crop = false;
//cropImageSrc: string ="https://helpx.adobe.com/content/dam/help/en/stock/how-to/visual-reverse-image-search/jcr_content/main-pars/image/visual-reverse-image-search-v2_intro.jpg";
this.cropperConfig = null;
this.pending = false;
this.previewHeightStyle = null;
this.propagateChange = (_) => {
};
this.markAsTouched = (_) => {
};
}
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched(fn) {
this.markAsTouched = fn;
}
setDisabledState(isDisabled) {
}
change($event) {
this.propagateChange($event.target.value);
}
writeValue(value) {
if (value !== null) {
this.value = value;
this.cropImageSrc = value;
this.previewImageUrl = value;
}
}
ngOnInit() {
this.widthHeightRatio = this.height / this.width;
this.cropperConfig = new ImageCropperConfig(this.width, this.height, [4, 8, 16]);
this.resize();
}
resize() {
this.previewHeightStyle = this.sanitizer.bypassSecurityTrustStyle(this.host.nativeElement.clientWidth * this.widthHeightRatio + 'px');
}
openCropImageDialog($event) {
this.fileService.getBase64($event.target.files[0]).then(x => {
this.cropImageSrc = x;
this.crop = true;
document.body.style.overflowY = "hidden";
});
}
showImage($event) {
this.hideImageCroper();
this.previewImageUrl = $event;
this.value = $event;
this.propagateChange(this.value);
}
hideImageCroper() {
this.cropImageSrc = null;
this.crop = false;
this.imageInput.nativeElement.value = '';
document.body.style.overflowY = "auto";
}
};
InputImageComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: FileService },
{ type: DomSanitizer }
];
__decorate([
Input()
], InputImageComponent.prototype, "invalid", void 0);
__decorate([
Input()
], InputImageComponent.prototype, "width", void 0);
__decorate([
Input()
], InputImageComponent.prototype, "height", void 0);
__decorate([
ViewChild('imageInput')
], InputImageComponent.prototype, "imageInput", void 0);
__decorate([
HostListener('window:resize')
], InputImageComponent.prototype, "resize", null);
InputImageComponent = InputImageComponent_1 = __decorate([
Component({
selector: 'fg-input-image',
template: "\n\n<div [class.invalid]=\"invalid\" [style.height]=\"previewHeightStyle\" *ngIf=\"value===null&&pending===false\"\n class=\"imageInputWrapper noselect\" (click)=\"imageInput.click()\">\n <div class=\"placeholderWrapper\">\n <div class=\"icon\">\n <svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"27.949\" height=\"27.949\" viewBox=\"0 0 27.949 27.949\">\n <path id=\"ic_add_24px\" d=\"M32.949,20.971H20.971V32.949H16.978V20.971H5V16.978H16.978V5h3.993V16.978H32.949Z\"\n transform=\"translate(-5 -5)\"/>\n </svg>\n </div>\n <div class=\"text\">Add image</div>\n </div>\n</div>\n\n<div [style.height]=\"previewHeightStyle\"\n [style.background-image]=\"'url('+previewImageUrl+')'\" *ngIf=\"value!==null&&pending===false\"\n class=\"imageInputWrapper withImage noselect\" (click)=\"imageInput.click()\">\n <div class=\"placeholderWrapper\">\n <div class=\"icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n <path\n d=\"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z\"/>\n <path d=\"M0 0h24v24H0z\" fill=\"none\"/>\n </svg>\n </div>\n <div class=\"text\">Change image</div>\n </div>\n</div>\n\n<div [style.height]=\"previewHeightStyle\" *ngIf=\"pending===true\"\n class=\"imageInputWrapper withImage noselect\" (click)=\"imageInput.click()\">\n <div class=\"placeholderWrapper\">\n <div class=\"icon\">\n <div class=\"spinner\">\n <div class=\"rect1\"></div>\n <div class=\"rect2\"></div>\n <div class=\"rect3\"></div>\n <div class=\"rect4\"></div>\n <div class=\"rect5\"></div>\n </div>\n </div>\n </div>\n</div>\n\n<input class=\"hidden\" (change)=\"openCropImageDialog($event);\" type=\"file\" accept=\