UNPKG

ngx-image-drawing-zone

Version:

![Screenshot](https://github.com/lea-so123/GitHub/main/my-workspace/projects/ngx-image-drawing-zone/.github/screenshot.jpg)

1,330 lines 66.5 kB
import { NgTemplateOutlet, NgStyle, NgClass, CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { EventEmitter, Component, Input, Output, NgModule } from '@angular/core';
import { fabric } from 'fabric';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { MatIconModule } from '@angular/material/icon';

const I18nFr = {
    saveBtn: 'Enregistrer',
    cancelBtn: 'Annuler',
    loadImage: 'Charger une image depuis votre PC',
    loadImageUrl: 'Charger une image depuis une URL',
    loading: 'Chargement',
    loadError: 'Erreur de chargement %@',
    removeImage: 'Supprimer l\'image',
    sizes: {
        small: 'Petit',
        medium: 'Moyen',
        large: 'Gros'
    },
    undo: 'Annuler',
    redo: 'Répter',
    clear: 'Effacer',
    colors: {
        black: 'Noir',
        white: 'Blanc',
        yellow: 'Jaune',
        red: 'Rouge',
        green: 'Vert',
        blue: 'Blue',
        purple: 'Violet'
    },
    tools: {
        brush: 'Pinceau'
    }
};
const I18nEn = {
    saveBtn: 'Save',
    cancelBtn: 'Cancel',
    loadImage: 'Load image',
    loadImageUrl: 'Load image from URL',
    loading: 'Loading',
    loadError: 'Error loading %@',
    removeImage: 'Remove image',
    sizes: {
        small: 'Small',
        medium: 'Medium',
        large: 'Large'
    },
    resize: "Resize",
    undo: 'Undo',
    redo: 'Redo',
    clear: 'Clear',
    crop: 'Crop',
    mask: "Mask",
    rotate: "Rotate",
    colors: {
        black: 'Black',
        white: 'White',
        yellow: 'Yellow',
        red: 'Red',
        green: 'Green',
        blue: 'Blue',
        purple: 'Purple',
    },
    tools: {
        brush: 'Brush'
    }
};
const I18nHe = {
    saveBtn: 'שמירה',
    cancelBtn: 'ביטול',
    loadImage: 'טוען תמונה',
    loadImageUrl: 'טוען תמונה מנתיב',
    loading: 'בטעינה',
    loadError: 'שגיאה בטעינה',
    removeImage: 'הסרת תמונה',
    sizes: {
        small: 'קטן',
        medium: 'בינוני',
        large: 'גדול'
    },
    rotate: "הפיכת תמונה",
    resize: "שנה גודל",
    undo: 'ביטול',
    redo: 'שחזור',
    clear: 'ניקןי',
    crop: 'חיתוך תמונה',
    mask: 'ריבוע בחירה',
    colors: {
        black: 'שחור',
        white: 'לבן',
        yellow: 'צהוב',
        red: 'אדום',
        green: 'ירוק',
        blue: 'כחול',
        purple: 'סגול',
    },
    tools: {
        brush: 'מברשת'
    }
};
const i18nLanguages = {
    fr: I18nFr,
    en: I18nEn,
    he: I18nHe
};

class ImageDrawingComponent {
    constructor(zone) {
        this.zone = zone;
        this.saveBtnClass = "button btn-primary";
        this.cancelBtnClass = "button btn-light";
        this.forceSizeCanvas = true;
        this.forceSizeExport = false;
        this.enableRemoveImage = false;
        this.enableLoadAnotherImage = false;
        this.enableTooltip = true;
        this.showCancelButton = true;
        this.locale = 'en';
        /* @deprecated Use i18n.saveBtn */
        this.saveBtnText = 'Save';
        /* @deprecated Use i18n.cancelBtn */
        this.cancelBtnText = 'Cancel';
        /* @deprecated Use i18n.loading */
        this.loadingText = 'Loading…';
        /* @deprecated Use i18n.loadError */
        this.errorText = 'Error loading %@';
        this.outputMimeType = 'image/jpeg';
        this.outputQuality = 0.8;
        this.borderCss = 'none';
        this.drawingSizes = {
            small: 5,
            medium: 10,
            large: 25,
        };
        this.colors = {
            black: '#000',
            white: '#fff',
            yellow: '#ffeb3b',
            red: '#f44336',
            blue: '#2196f3',
            green: '#4caf50',
            purple: '#7a08af',
        };
        this.save = new EventEmitter();
        this.cancel = new EventEmitter();
        this.currentTool = '';
        this.currentSize = 'medium';
        this.currentColor = 'black';
        this.i18n = I18nEn;
        this.shapesNames = [
            { shape: 'rectangle', icon: 'rectangle' },
            { shape: 'circle', icon: 'circle' },
            { shape: 'line', icon: ' horizontal_rule' },
            { shape: 'arrow', icon: 'arrow_back' }
        ];
        this.canUndo = false;
        this.canRedo = false;
        this.isShapeMode = false;
        this.shapeType = '';
        this.isLoading = false;
        this.hasError = false;
        this.errorMessage = '';
        this.shapedone = false;
        this.stack = [];
        this.stackUndo = [];
        this.stackUndoLocation = [];
        this.stackRedoLocation = [];
        this.colorsName = [];
        this.drawingSizesName = [];
        this.isCrop = false;
        this.pos = [0, 0];
        this.mousex = 0;
        this.mousey = 0;
        this.disabled = true;
        this.lastSelectedPicture = null;
        this.isInsertingCropRectangle = false;
        this.done = false;
    }
    get commons() {
        return {
            originX: 'center',
            originY: 'center',
            stroke: this.currentColor,
            strokeWidth: this.drawingSizes[this.currentSize]
        };
    }
    get commons1() {
        return {
            stroke: this.currentColor,
            strokeWidth: this.drawingSizes[this.currentSize]
        };
    }
    ngOnInit() {
        this.colorsName = Object.keys(this.colors);
        this.drawingSizesName = Object.keys(this.drawingSizes);
        this.initClipPath();
        this.canvas = new fabric.Canvas('canvas', {
            hoverCursor: 'pointer',
            selection: true,
            preserveObjectStacking: true,
            //clipPath:clipPath
            //isDrawingMode: true,
        });
        this.canvas.backgroundColor = 'white';
        if (this.src) {
            this.importPhotoFromSrc(this.src);
            this.r = document.getElementById('canvas').getBoundingClientRect();
            this.pos[0] = this.r.left;
            this.pos[1] = this.r.top;
        }
        else {
            if (!this.width || !this.height) {
                throw new Error('No width or hight given !');
            }
            this.canvas.setWidth(this.width);
            this.canvas.setHeight(this.height);
        }
        //this.canvas.on('')
        this.canvas.on('path:created', () => {
            this.stack = [];
            this.setUndoRedo();
        });
        this.canvas.on('object:added', (e) => {
        });
        this.canvas.on('object:modified', (e) => {
            if (this.currentTool === 'resize') {
                const newWidth = e.target.width * e.target.scaleX;
                const newHeight = e.target.height * e.target.scaleY;
                e.target.set({ opacity: 1 });
                debugger;
                //var newWidth = (Math.round(e.target.width/ canvasGrid)) * canvasGrid;
                //var newHeight = (Math.round(e.target.height / canvasGrid)) * canvasGrid;
                if (e.target.width !== newWidth) {
                    //e.target.set({ width: newWidth, height: newHeight, scaleX: 1, scaleY: 1, });
                }
                this.imageUsed.scaleToWidth(e.target.width * e.target.scaleX);
                this.imageUsed.scaleToHeight(e.target.height * e.target.scaleY);
                this.canvas.setWidth(e.target.width * e.target.scaleX);
                this.canvas.setHeight(e.target.height * e.target.scaleY);
                e.target.setCoords();
                this.canvas.renderAll();
                const imageStr = this.canvas.toDataURL({
                    format: 'jpeg'
                });
                this.canvas.remove(this.imageUsed);
                this.canvas.getObjects().forEach(e => e.opacity = 0);
                this.selectTool('');
                //this.canvas.getObjects()[0].opacity=1
                this.importPhotoFromSrc(imageStr, false, true);
            }
            //this.setUndoRedo()
        });
        this.canvas.on('mouse:down', (o) => {
            if (this.isInsertingCropRectangle == true) {
                console.log('mouse down done = ' + this.done);
                if (this.done) {
                    this.canvas.renderAll();
                    return;
                }
                this.isDown = true;
                var pointer = this.canvas.getPointer(o.e);
                this.origX = pointer.x;
                this.origY = pointer.y;
                this.crop_rect = new fabric.Rect({
                    left: this.origX,
                    top: this.origY,
                    width: pointer.x - this.origX,
                    height: pointer.y - this.origY,
                    opacity: .3,
                    transparentCorners: false,
                    selectable: true,
                    //id: 'mask'
                });
                this.mask = this.crop_rect;
                this.canvas.add(this.crop_rect);
                this.setUndoRedo();
                this.canvas.renderAll();
            }
            else if (this.isShapeMode === true) {
                this.isDown = true;
                if (this.shapeType === 'rectangle') {
                    this.shapePoint = this.canvas.getPointer(o.e);
                    this.shape_rect = new fabric.Rect({
                        ...this.commons,
                        left: this.shapePoint.x,
                        top: this.shapePoint.y,
                        fill: 'transparent',
                        width: this.shapePoint.x - this.shapePoint.x,
                        height: this.shapePoint.y - this.shapePoint.y,
                        //centeredRotation:true,
                        //centeredScaling:true,
                        selectable: true,
                    });
                    this.canvas.add(this.shape_rect);
                    //this.setUndoRedo();
                    this.canvas.renderAll();
                }
                else if (this.shapeType === 'circle') {
                    this.shapePoint = this.canvas.getPointer(o.e);
                    this.shape_circle = new fabric.Circle({
                        ...this.commons,
                        left: this.shapePoint.x,
                        top: this.shapePoint.y,
                        fill: 'transparent',
                        radius: this.shapePoint.x - this.shapePoint.x,
                        selectable: true,
                    });
                    this.canvas.add(this.shape_circle);
                    //this.setUndoRedo();
                    this.canvas.renderAll();
                }
                else if (this.shapeType === 'line') {
                    this.shapePoint = this.canvas.getPointer(o.e);
                    this.shape_line = new fabric.Line([this.shapePoint.x, this.shapePoint.y, this.shapePoint.x, this.shapePoint.y], this.commons);
                    this.canvas.add(this.shape_line);
                    this.canvas.renderAll();
                }
                else if (this.shapeType === 'arrow') {
                    this.shapePoint = this.canvas.getPointer(o.e);
                    var angle = Math.atan2(this.shapePoint.y - this.shapePoint.y, this.shapePoint.x - this.shapePoint.x);
                    angle *= 180 / Math.PI;
                    angle += 90;
                    this.shape_line = new fabric.Line([this.shapePoint.x, this.shapePoint.y, this.shapePoint.x, this.shapePoint.y], this.commons);
                    this.shape_arrow = new fabric.Triangle({
                        ...this.commons,
                        angle: angle,
                        top: this.shape_line.y2,
                        left: this.shape_line.x2,
                        width: 10,
                        height: 10
                    });
                    this.shape_line_copy = new fabric.Line([this.shapePoint.x, this.shapePoint.y, this.shapePoint.x, this.shapePoint.y], this.commons);
                    this.shape_arrow_copy = new fabric.Triangle({
                        ...this.commons,
                        angle: angle,
                        top: this.shape_line.y2,
                        left: this.shape_line.x2,
                        width: 10,
                        height: 10
                    });
                    this.canvas.add(this.shape_line);
                    this.canvas.add(this.shape_arrow);
                    this.canvas.renderAll();
                }
            }
        });
        this.canvas.on('mouse:move', (o) => {
            if (this.isInsertingCropRectangle == true) {
                console.log('mouse move done = ' + this.done);
                if (this.done) {
                    this.canvas.renderAll();
                    return;
                }
                if (!this.isDown)
                    return;
                var pointer = this.canvas.getPointer(o.e);
                if (this.origX > pointer.x) {
                    this.crop_rect.set({
                        left: Math.abs(pointer.x)
                    });
                }
                if (this.origY > pointer.y) {
                    this.crop_rect.set({
                        top: Math.abs(pointer.y)
                    });
                }
                this.crop_rect.set({
                    width: Math.abs(this.origX - pointer.x)
                });
                this.crop_rect.set({
                    height: Math.abs(this.origY - pointer.y)
                });
                this.crop_rect.setCoords();
                this.canvas.renderAll();
            }
            else if (this.isShapeMode === true) {
                if (!this.isDown)
                    return;
                if (this.shapeType === 'rectangle') {
                    var pointer = this.canvas.getPointer(o.e);
                    if (this.shapePoint.x > pointer.x) {
                        this.shape_rect.set({
                            left: Math.abs(pointer.x)
                        });
                    }
                    if (this.shapePoint.y > pointer.y) {
                        this.shape_rect.set({
                            top: Math.abs(pointer.y)
                        });
                    }
                    this.shape_rect.set({
                        width: Math.abs(this.shapePoint.x - pointer.x)
                    });
                    this.shape_rect.set({
                        height: Math.abs(this.shapePoint.y - pointer.y)
                    });
                    this.shape_rect.setCoords();
                    this.canvas.renderAll();
                }
                else if (this.shapeType === 'circle') {
                    var pointer = this.canvas.getPointer(o.e);
                    if (this.shapePoint.x > pointer.x) {
                        this.shape_circle.set({
                            left: Math.abs(pointer.x)
                        });
                    }
                    if (this.shapePoint.y > pointer.y) {
                        this.shape_circle.set({
                            top: Math.abs(pointer.y)
                        });
                    }
                    this.shape_circle.set({
                        radius: Math.abs(this.shapePoint.x - pointer.x) / 2
                    });
                    // this.shape_circle.set({
                    //  height: Math.abs(this.shapePoint.y - pointer.y)
                    //});
                    this.shape_circle.setCoords();
                    this.canvas.renderAll();
                }
                else if (this.shapeType === 'line') {
                    var pointer = this.canvas.getPointer(o.e);
                    if (this.shapePoint.x > pointer.x) {
                        this.shape_line.set({
                            left: Math.abs(pointer.x)
                        });
                    }
                    if (this.shapePoint.y > pointer.y) {
                        this.shape_line.set({
                            top: Math.abs(pointer.y)
                        });
                    }
                    this.shape_line.set({
                        x2: pointer.x,
                        y2: pointer.y
                    });
                    this.shape_line.setCoords();
                    this.canvas.renderAll();
                }
                else if (this.shapeType === 'arrow') {
                    var pointer = this.canvas.getPointer(o.e);
                    console.log(pointer);
                    console.log(this.shapePoint);
                    const py = pointer.y - this.shapePoint.y;
                    const px = pointer.x - this.shapePoint.x;
                    this.shape_line.set({
                        x2: pointer.x,
                        y2: pointer.y
                    });
                    this.shape_line_copy.set({
                        x2: pointer.x,
                        y2: pointer.y
                    });
                    this.shape_line.setCoords();
                    var angle = Math.atan2(py, px);
                    angle *= 180 / Math.PI;
                    angle += 90;
                    let pointX;
                    let pointY;
                    if (pointer.x > this.shapePoint.x) {
                        pointX = pointer.x + 15;
                    }
                    else if (pointer.x < this.shapePoint.x) {
                        pointX = pointer.x - 15;
                    }
                    else {
                        pointX = pointer.x;
                    }
                    if (pointer.y > this.shapePoint.y) {
                        pointY = pointer.y + 7;
                    }
                    else if (pointer.y < this.shapePoint.y) {
                        pointY = pointer.y - 7;
                    }
                    else {
                        pointY = pointer.y;
                    }
                    this.shape_arrow.set({
                        angle: angle,
                        top: pointer.y,
                        left: pointer.x
                    });
                    this.shape_arrow_copy.set({
                        angle: angle,
                        top: pointer.y,
                        left: pointer.x
                    });
                    console.log(this.shape_arrow);
                    console.log(this.shape_line);
                    this.shape_arrow.setCoords();
                    this.canvas.renderAll();
                }
            }
        });
        this.canvas.on('mouse:up', (o) => {
            if (this.isInsertingCropRectangle == true) {
                console.log('mouse up done = ' + this.done);
                if (this.done) {
                    this.canvas.renderAll();
                    return;
                }
                this.isDown = false;
                this.crop_rect.set({
                    selectable: true
                });
                this.done = true;
            }
            else if (this.isShapeMode === true) {
                if (this.shapedone)
                    return;
                if (this.shapeType === 'arrow') {
                    debugger;
                    const line = new fabric.Line([this.shape_line.x1, this.shape_line.y1, this.shape_line.x2, this.shape_line.y2], this.commons1);
                    line.set({
                        x1: this.shape_line.x1,
                        y1: this.shape_line.y1,
                        x2: this.shape_line.x2,
                        y2: this.shape_line.y2
                    });
                    const arrow = new fabric.Triangle({
                        ...this.commons1,
                        angle: this.shape_arrow.angle,
                        top: this.shape_arrow.top,
                        left: this.shape_arrow.left,
                        width: 10,
                        height: 10
                    });
                    line.setCoords();
                    arrow.setCoords();
                    var obj = [this.shape_arrow_copy, this.shape_line_copy];
                    let myShape = new fabric.Group(obj, {
                        left: Math.min(this.shape_line_copy.x1, this.shape_line_copy.x2),
                        top: Math.min(this.shape_line_copy.y1, this.shape_line_copy.y2)
                    });
                    myShape.setCoords();
                    console.log(myShape);
                    this.canvas.add(myShape);
                    this.canvas.renderAll();
                    this.canvas.remove(this.shape_line);
                    this.canvas.remove(this.shape_arrow);
                    this.canvas.renderAll();
                    this.shapedone = true;
                    //this.isDown = false;
                    //this.shapeType=''
                    //this.isShapeMode=false;
                    this.selectTool('');
                    this.setUndoRedo();
                    this.canvas.renderAll();
                }
                else {
                    //this.isDown = false;
                    //this.shapeType=''
                    //this.isShapeMode=false;
                    this.selectTool('');
                    this.setUndoRedo();
                    this.canvas.renderAll();
                }
            }
        });
        this.canvas.on('selection:created', (event) => {
            console.log("canvas.on('selection:created'");
            this.selectionChanged(event);
        });
        this.canvas.on('selection:updated', (event) => {
            console.log("canvas.on('selection:updated'");
            this.selectionChanged(event);
        });
        this.selectColor(this.currentColor);
        this.selectDrawingSize(this.currentSize);
        if (this.locale && i18nLanguages[this.locale.toLowerCase()]) {
            this.i18n = i18nLanguages[this.locale.toLowerCase()];
        }
        // FIXME remove after a while because properties are now deprecated
        if (this.saveBtnText) {
            this.i18n.saveBtn = this.saveBtnText;
        }
        if (this.cancelBtnText) {
            this.i18n.cancelBtn = this.cancelBtnText;
        }
        if (this.loadingText) {
            this.i18n.loading = this.loadingText;
        }
        if (this.errorText) {
            this.i18n.loadError = this.errorText;
        }
    }
    selectionChanged(event) {
        console.log("selectionChanged");
        console.log("selectionChanged type = " + event.target?.type);
        switch (event.target?.type) {
            case 'textbox':
                break;
            case 'image':
                this.lastSelectedPicture = event.target;
                break;
            case 'rect':
                break;
            case 'group':
                break;
            default:
                break;
        }
    }
    rotate(degrees, undo = true) {
        this.selectTool('rotate');
        //this.canvas.setWidth(this.canvas.width+500)
        //this.canvas.setHeight(this.canvas.height+500)
        this.canvas.renderAll();
        if (undo) {
            this.stackUndoLocation.push({ type: 'rotate', loc: this.canvas.getObjects().length });
            this.stackUndo.push(this.imageUsed);
            this.setUndoRedo();
        }
        const w = this.canvas.width;
        const h = this.canvas.height;
        this.canvas.setWidth(h);
        this.canvas.setHeight(w);
        let i = 0;
        this.canvas.getObjects().forEach((value) => {
            console.log(value);
            const t = value.top;
            const l = value.left;
            console.log("T L", value.top, value.left);
            //const dd=(value?.angle+degrees)
            //const de=( (dd % 360)* Math.PI) / 180
            value.centeredRotation = true;
            if (i > 0) {
                this.canvas.setActiveObject(value);
            }
            value.rotate(value?.angle + degrees).setCoords();
            console.log("T1 L1", value.top, value.left);
            const w1 = value.width > this.canvas.width && value.width !== this.canvas.height ? this.canvas.width : value.width;
            ;
            const h1 = value.height > this.canvas.height && value.height !== this.canvas.width ? this.canvas.height : value.height;
            //value.originX='left'
            //value.originY='top'
            console.log("w1 h1 ", w1, h1);
            //value.or
            let pref = Math.abs(w1 / 2 - h1 / 2);
            console.log("pref ", pref);
            // value.originX='left'
            // value.originY='top'
            console.log("i ", i);
            if (i === 0) {
                if ((value.angle % 360 === 90 || value.angle % 360 === 270)) {
                    if (h > w) {
                        pref = pref * -1;
                    }
                    const t1 = t - value.top;
                    const l1 = h1 - value.left;
                    console.log(t1, l1);
                    value.top = value.top + pref;
                    value.left = value.left - pref;
                }
                //   if(value.angle%360===270){
                //     const t1=t-value.top;
                //     const l1=l-value.left;
                //     console.log(t1,l1)
                //     value.top=value.top+pref;
                //     value.left=value.left-pref;
                //   }
                if (value.angle % 360 === 180 || value.angle % 360 === 0) {
                    if (h < w) {
                        pref = pref * -1;
                    }
                    const t1 = h1 + value.top;
                    const l1 = l - value.left;
                    console.log(t1, l1);
                    value.top = value.top - pref;
                    value.left = value.left + pref;
                }
                //   if(value.angle%360===0){
                //     const t1=h1-value.top;
                //     const l1=l-value.left;
                //     console.log(t1,l1)
                //     value.top=value.top-pref;
                //     value.left=value.left+pref;
                //   }
            }
            else {
                // if(value.angle%360===0){
                //     value.top=300;
                //     value.left=300;
                //    console.log("TT LL",value.top,value.left)
                // }else{
                value.top = l;
                value.left = this.canvas.width - t;
                console.log("TT LL", value.top, value.left);
                //}
            }
            i = i + 1;
            console.log(value);
        });
        //imageR.rotate(Math.PI / 2)
        // imageR.snapAngle =90;
        this.canvas.renderAll();
    }
    shape(shapeT) {
        this.selectTool('shape');
        this.shapedone = false;
        this.isShapeMode = true;
        this.shapeType = shapeT;
    }
    rescaleMask(target, mask) {
        mask.scaleX = 1;
        mask.scaleY = 1;
        mask.scaleX /= target.scaleX;
        mask.scaleY /= target.scaleY;
        const targetCenterX = target.width * target.scaleX / 2;
        const targetCenterY = target.height * target.scaleY / 2;
        const maskOverlapX = mask.left - target.left;
        const maskOverlapY = mask.top - target.top;
        let centerBasedX = maskOverlapX - targetCenterX;
        let centerBasedY = maskOverlapY - targetCenterY;
        if (maskOverlapX >= targetCenterX) {
            centerBasedX = (maskOverlapX - targetCenterX) / target.scaleX;
        }
        else {
            centerBasedX = (-(targetCenterX) + maskOverlapX) / target.scaleX;
        }
        if (maskOverlapY >= targetCenterY) {
            centerBasedY = (maskOverlapY - targetCenterY) / target.scaleY;
        }
        else {
            centerBasedY = (-(targetCenterY) + maskOverlapY) / target.scaleY;
        }
        console.log('targetleft = ' + target.left);
        console.log('targettop = ' + target.top);
        console.log('targetCenterX = ' + targetCenterX);
        console.log('targetCenterY = ' + targetCenterY);
        console.log('maskleft = ' + mask.left);
        console.log('masktop = ' + mask.top);
        console.log('maskOverlapX = ' + maskOverlapX);
        console.log('maskOverlapY = ' + maskOverlapY);
        console.log('centerBasedX = ' + centerBasedX);
        console.log('centerBasedY = ' + centerBasedY);
        mask.left = centerBasedX;
        mask.top = centerBasedY;
        mask.originX = 'left';
        mask.originY = 'top';
        mask.setCoords();
        mask.dirty = true;
        this.canvas.renderAll();
        //var newMask = mask;
        return (mask);
    }
    initClipPath() {
        this.clipPath = new fabric.Rect({
            //left: 100,
            //top: 100,
            fill: 'transparent',
            originX: 'left',
            originY: 'top',
            stroke: '#ccc',
            strokeDashArray: [2, 2],
            opacity: 1,
            width: 1,
            height: 1
        });
    }
    // Tools
    selectTool(tool) {
        this.currentTool = tool;
        if (this.currentTool === 'brush') {
            this.canvas.isDrawingMode = true;
        }
        else {
            this.canvas.isDrawingMode = false;
        }
        if (this.currentTool !== 'shape') {
            this.isDown = false;
            this.shapeType = '';
            this.isShapeMode = false;
        }
    }
    selectDrawingSize(size) {
        this.currentSize = size;
        if (this.canvas) {
            this.canvas.freeDrawingBrush.width = this.drawingSizes[size];
        }
    }
    selectColor(color) {
        this.currentColor = color;
        if (this.canvas) {
            this.canvas.freeDrawingBrush.color = this.colors[color];
        }
    }
    maskC() {
        this.isInsertingCropRectangle = true;
        this.selectTool('mask');
        this.canvas.discardActiveObject();
        this.target.selectable = false;
        this.target.setCoords();
        this.target.dirty = true;
        //this.lastSelectedPicture.selectable = false;
        //this.lastSelectedPicture.setCoords();
        //this.lastSelectedPicture.dirty = true;
        this.canvas.renderAll();
        this.setUndoRedo();
        this.canvas.discardActiveObject();
        this.canvas.isDrawingMode = false;
    }
    // Actions
    crop() {
        if (this.target !== null && this.mask !== null && this.done) {
            this.selectTool('crop');
            this.target.setCoords();
            // Re-scale mask
            //this.mask = this.rescaleMask(this.target, this.mask);
            this.mask.setCoords();
            // Do the crop
            //this.target.clipPath = this.mask;
            //this.target.clipPath.setCoords();
            //this.target.dirty=true;
            //this.canvas.setActiveObject(this.target);
            //this.canvas.bringToFront(this.target);
            //this.target.clipPath.selectable = true;
            this.setUndoRedo();
            //this.stackUndoLocation.push(this.canvas.getObjects().length-2)
            //this.stackUndo.push(this.mask);
            this.canvas.remove(this.mask);
            this.canvas.renderAll();
            this.stackUndoLocation.push({ type: '', loc: this.canvas.getObjects().length - 1 });
            this.stackUndo.push(this.imageUsed);
            this.setUndoRedo();
            const scale2 = Math.min(this.canvas.getWidth() / this.crop_rect.width, this.canvas.getHeight() / this.crop_rect.height);
            const imageStr = this.canvas.toDataURL({
                width: this.crop_rect.width, //this.target.clipPath.width,
                height: this.crop_rect.height,
                left: this.crop_rect.left, //+this.canvas.width/2,
                top: this.crop_rect.top, //+this.canvas.height/2,
                quality: 1,
                multiplier: scale2,
                format: 'jpeg'
            });
            this.canvas.remove(this.imageUsed);
            this.canvas.getObjects().forEach(e => e.opacity = 0);
            //this.canvas.getObjects()[0].opacity=1
            this.importPhotoFromSrc(imageStr);
            this.imageUsed.sendToBack();
            this.canvas.renderAll();
            this.setUndoRedo();
            console.log(this.target);
            this.isInsertingCropRectangle = false;
            this.done = false;
            this.selectTool('');
        }
        //this.disabled=false;
    }
    resize() {
        this.selectTool('resize');
        this.stackUndoLocation.push({ type: '', loc: this.canvas.getObjects().length - 1 });
        this.stackUndo.push(this.imageUsed);
        this.setUndoRedo();
        const imageStr = this.canvas.toDataURL({
            format: 'jpeg'
        });
        this.canvas.remove(this.imageUsed);
        this.canvas.getObjects().forEach(e => e.opacity = 0);
        //this.canvas.getObjects()[0].opacity=1
        this.importPhotoFromSrc(imageStr, true);
        //this.canvas.setWidth(this.canvas.width+500)
        //this.canvas.setHeight(this.canvas.height+500)
        this.canvas.renderAll();
    }
    undo() {
        if (this.canUndo) {
            debugger;
            if (this.stackUndo.length > 0) {
                if (this.stackUndoLocation[this.stackUndoLocation.length - 1].type === 'rotate') {
                    const ob = this.stackUndo.pop();
                    const l = this.stackUndoLocation.pop().loc;
                    this.setUndoRedo();
                    this.rotate(-90, false);
                    this.stack.push('rotate');
                    this.stackRedoLocation.push({ type: 'rotate', loc: this.canvas.getObjects().length });
                    this.setUndoRedo();
                }
                else if (this.canvas.getObjects().length - this.stackUndoLocation[this.stackUndoLocation.length - 1].loc > 1) {
                    const lastId = this.canvas.getObjects().length - 1;
                    const lastObj = this.canvas.getObjects()[lastId];
                    this.done = false;
                    this.stack.push(lastObj);
                    this.canvas.remove(lastObj);
                    this.setUndoRedo();
                    this.canvas.renderAll();
                }
                else {
                    const ob = this.stackUndo.pop();
                    const l = this.stackUndoLocation.pop().loc;
                    if (ob instanceof fabric.Image) {
                        this.stack.push(this.imageUsed);
                        for (var i = l; i >= 0; i--) {
                            this.canvas.getObjects()[i].opacity = 1;
                        }
                        this.setUndoRedo();
                        this.canvas.remove(this.imageUsed);
                        this.importPhotoFromSrc(ob.getSrc());
                        debugger;
                    }
                    else {
                        this.canvas.add(ob);
                    }
                    this.canvas.renderAll();
                }
            }
            else {
                const lastId = this.canvas.getObjects().length - 1;
                const lastObj = this.canvas.getObjects()[lastId];
                this.done = false;
                this.stack.push(lastObj);
                this.canvas.remove(lastObj);
                this.setUndoRedo();
                this.canvas.renderAll();
            }
        }
    }
    redo() {
        if (this.canRedo) {
            const firstInStack = this.stack.splice(-1, 1)[0];
            if (firstInStack) {
                if (firstInStack instanceof fabric.Image) {
                    this.stackUndoLocation.push({ type: '', loc: this.canvas.getObjects().length - 1 });
                    this.stackUndo.push(this.imageUsed);
                    this.canvas.remove(this.imageUsed);
                    this.importPhotoFromSrc(firstInStack.getSrc());
                    this.setUndoRedo();
                }
                else if (firstInStack === 'rotate') {
                    this.rotate(90);
                }
                else {
                    this.canvas.insertAt(firstInStack, this.canvas.getObjects().length, false);
                    this.setUndoRedo();
                }
            }
        }
    }
    clearCanvas() {
        if (this.canvas) {
            this.canvas.clipPath = null;
            this.canvas.remove(...this.canvas.getObjects());
            //this.canvas.clear()
            this.setUndoRedo();
        }
    }
    saveImage() {
        if (!this.forceSizeExport || (this.forceSizeExport && this.width && this.height)) {
            const canvasScaledElement = document.createElement('canvas');
            const canvasScaled = new fabric.Canvas(canvasScaledElement);
            canvasScaled.backgroundColor = 'white';
            let imageStr = null;
            new Observable(observer => {
                if (this.imageUsed) {
                    if (this.target.clipPath) {
                        debugger;
                        imageStr = this.canvas.toDataURL({
                            width: this.target.clipPath.width,
                            height: this.target.clipPath.height,
                            left: this.target.clipPath.left + this.canvas.width / 2,
                            top: this.target.clipPath.top + this.canvas.height / 2,
                            format: 'jpeg'
                        });
                        console.log(imageStr);
                    }
                    if (this.forceSizeExport) {
                        canvasScaled.setWidth(this.width);
                        canvasScaled.setHeight(this.height);
                        this.imageUsed.cloneAsImage(imageCloned => {
                            imageCloned.scaleToWidth(this.width, false);
                            imageCloned.scaleToHeight(this.height, false);
                            canvasScaled.setBackgroundImage(imageCloned, (img) => {
                                if (!img) {
                                    observer.error(new Error('Impossible to draw the image on the temporary canvas'));
                                }
                                observer.next(canvasScaled);
                                observer.complete();
                            }, {
                                crossOrigin: 'anonymous',
                                originX: 'left',
                                originY: 'top'
                            });
                        });
                    }
                    else {
                        //canvasScaled.clipPath=this.mask
                        canvasScaled.setBackgroundImage(this.target, (img) => {
                            if (!img) {
                                observer.error(new Error('Impossible to draw the image on the temporary canvas'));
                            }
                            //canvasScaled.clipPath=this.clipPath
                            //(canvasScaled.backgroundImage as fabric.Image).clipPath=(this.canvas.backgroundImage as fabric.Image).clipPath
                            console.log(this.canvas.width);
                            if (img.angle % 360 === 90 || img.angle % 360 === 270) {
                                canvasScaled.setWidth(img.height * this.imageUsed.scaleX);
                                canvasScaled.setHeight(img.width * this.imageUsed.scaleY);
                            }
                            else {
                                canvasScaled.setWidth(img.width * this.imageUsed.scaleX);
                                canvasScaled.setHeight(img.height * this.imageUsed.scaleY);
                            }
                            observer.next(canvasScaled);
                            observer.complete();
                        }, {
                            crossOrigin: 'anonymous',
                            originX: 'left',
                            originY: 'top'
                        });
                        //(canvasScaled.backgroundImage as fabric.Image).clipPath=this.clipPath
                    }
                }
                else {
                    canvasScaled.setWidth(this.width);
                    canvasScaled.setHeight(this.height);
                }
            }).pipe(switchMap(() => {
                let process = of(canvasScaled);
                if (this.canvas.getObjects().length > 1) {
                    this.canvas.remove(this.imageUsed);
                    const ratioX = canvasScaled.getWidth() / this.canvas.getWidth();
                    const ratioY = canvasScaled.getHeight() / this.canvas.getHeight();
                    this.canvas.getObjects().forEach((originalObject, i) => {
                        process = process.pipe(switchMap(() => {
                            return new Observable(observerObject => {
                                originalObject.clone((clonedObject) => {
                                    clonedObject.set('left', originalObject.left * ratioX);
                                    clonedObject.set('top', originalObject.top * ratioY);
                                    clonedObject.scaleToWidth(originalObject.width * ratioX);
                                    clonedObject.scaleToHeight(originalObject.height * ratioY);
                                    canvasScaled.insertAt(clonedObject, i, false);
                                    canvasScaled.renderAll();
                                    observerObject.next(canvasScaled);
                                    observerObject.complete();
                                });
                            });
                        }));
                    });
                }
                return process;
            })).subscribe(() => {
                canvasScaled.renderAll();
                // console.log(
                //     canvasScaled.toDataURL(
                //         {width:this.clipPath.width,
                //             height:this.clipPath.height,
                //             left:(this.canvas.backgroundImage as fabric.Image).clipPath.left,
                //             top:(this.canvas.backgroundImage as fabric.Image).clipPath.top,
                //             format:'jpeg'
                //         }))
                const im = canvasScaled.toDataURL({
                    format: 'jpeg'
                });
                console.log(im);
                canvasScaled.getElement().toBlob((data) => this.zone.run(() => {
                    this.save.emit(data);
                }), this.outputMimeType, this.outputQuality);
            });
        }
        else {
            this.canvas.getElement().toBlob((data) => this.zone.run(() => {
                this.save.emit(data);
            }), this.outputMimeType, this.outputQuality);
        }
    }
    cancelAction() {
        this.cancel.emit();
    }
    getTextTranslated(name) {
        let strOk = name.split('.').reduce((o, i) => o[i], this.i18n);
        if (this.i18nUser) {
            try {
                const str = name.split('.').reduce((o, i) => o[i], this.i18nUser);
                if (str) {
                    strOk = str;
                }
            }
            catch (e) {
                // if we pass here, ignored
            }
        }
        if (!strOk) {
            console.error(name + ' translation not found !');
        }
        return strOk;
    }
    getTooltipTranslated(name) {
        if (this.enableTooltip) {
            return this.getTextTranslated(name);
        }
        else {
            return '';
        }
    }
    setUndoRedo() {
        this.canUndo = this.canvas.getObjects().length > 1 || this.stackUndo.length > 0;
        this.canRedo = this.stack.length > 0;
        // this.canvas.renderAll();
    }
    importPhotoFromFile(event) {
        if (event.target.files && event.target.files.length > 0) {
            const file = event.target.files[0];
            if (file.type.match('image.*')) {
                this.importPhotoFromBlob(file);
            }
            else {
                throw new Error('Not an image !');
            }
        }
    }
    removeImage() {
        if (this.imageUsed) {
            this.imageUsed.dispose();
            this.imageUsed = null;
        }
        this.canvas.backgroundImage = null;
        if (this.width && this.height) {
            this.canvas.setWidth(this.width);
            this.canvas.setHeight(this.height);
        }
        this.canvas.renderAll();
    }
    get hasImage() {
        return !!this.canvas.backgroundImage;
    }
    importPhotoFromSrc(src, select = false, stackundo = false) {
        this.isLoading = true;
        let isFirstTry = true;
        const imgEl = new Image();
        imgEl.setAttribute('crossorigin', 'anonymous');
        imgEl.crossOrigin = "anonymous";
        imgEl.src = src;
        imgEl.onerror = () => {
            // Retry with cors proxy
            /* if (isFirstTry) {
                 imgEl.src = 'https://cors-anywhere.herokuapp.com/' + this.src;
                 isFirstTry = false;
             }
              else */
            {
                this.isLoading = false;
                this.hasError = true;
                this.errorMessage = this.getTextTranslated('loadError').replace('%@', this.src);
            }
        };
        console.log(imgEl);
        const scaleWidth = this.canvas.getWidth() / imgEl.width;
        const scaleHeight = this.canvas.getHeight() / imgEl.height;
        const scale = Math.min(scaleWidth, scaleHeight);
        console.log(scale);
        imgEl.onload = () => {
            this.isLoading = false;
            this.imageUsed = new fabric.Image(imgEl, {
                selectable: false,
                width: imgEl.width,
                height: imgEl.height,
            });
            this.canvas.insertAt(this.imageUsed, 0, false);
            //this.canvas.sendToBack(this.imageUsed)
            this.canvas.width = imgEl.width;
            this.canvas.height = imgEl.height;
            //this.canvas.setActiveObject(this.imageUsed)
            console.log(this.imageUsed);
            this.imageUsed.cloneAsImage(image => {
                let width = imgEl.width;
                let height = imgEl.height;
                if (this.width && this.width < width) {
                    width = this.width;
                }
                if (this.height && this.height < height) {
                    height = this.height;
                }
                this.imageUsed.scaleToWidth(width);
                this.imageUsed.scaleToHeight(height);
                image.scaleToWidth(width, false);
                image.scaleToHeight(height, false);
                console.log(image, width, height);
                // this.canvas.setBackgroundImage(image, ((img: HTMLImageElement) => {
                //   if (img) {
                if (this.forceSizeCanvas) {
                    this.canvas.setWidth(width);
                    this.canvas.setHeight(height);
                }
                else {
                    this.canvas.setWidth(image.getScaledWidth());
                    this.canvas.setHeight(image.getScaledHeight());
                }
                //  }
                // }), {
                //   crossOrigin: 'Anonymous',
                //   originX: 'left',
                //    originY: 'top'
                //});
                this.target = this.imageUsed;
                this.target.selectable = select;
                if (select) {
                    this.target.lockMovementX = true;
                    this.target.lockMovementY = true;
                    this.canvas.setWidth(width + 500);
                    this.canvas.setHeight(height + 500);
                }
                if (stackundo) {
                    this.stackUndoLocation.push({ type: '', loc: this.canvas.getObjects().length - 1 });
                    this.stackUndo.push(this.imageUsed);
                    this.setUndoRedo();
                }
            });
        };
    }
    importPhotoFromBlob(file) {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = (evtReader) => {
            if (evtReader.target.readyState == FileReader.DONE) {
                this.importPhotoFromSrc(evtReader.target.result);
            }
        };
    }
    importPhotoFromUrl() {
        const url = prompt(this.getTooltipTranslated('loadImageUrl'));
        if (url) {
            this.importPhotoFromSrc(url);
        }
    }
    ngOnChanges(changes) {
        if (changes.src && !changes.src.firstChange && changes.src.currentValue) {
            if (typeof changes.src.currentValue === 'string') {
                this.importPhotoFromSrc(changes.src.currentValue);
            }
            else if (changes.src.currentValue) {
                this.importPhotoFromBlob(changes.src.currentValue);
            }
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageDrawingComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ImageDrawingComponent, isStandalone: true, selector: "image-drawing", inputs: { src: "src", width: "width", height: "height", saveBtnClass: "saveBtnClass", cancelBtnClass: "cancelBtnClass", forceSizeCanvas: "forceSizeCanvas", forceSizeExport: "forceSizeExport", enableRemoveImage: "enableRemoveImage", enableLoadAnotherImage: "enableLoadAnotherImage", enableTooltip: "enableTooltip", showCancelButton: "showCancelButton", i18nUser: ["i18n", "i18nUser"], locale: "locale", saveBtnText: "saveBtnText", cancelBtnText: "cancelBtnText", loadingText: "loadingText", errorText: "errorText", loadingTemplate: "loadingTemplate", errorTemplate: "errorTemplate", outputMimeType: "outputMimeType", outputQuality: "outputQuality", borderCss: "borderCss", drawingSizes: "drawingSizes", colors: "colors" }, outputs: { save: "save", cancel: "cancel" }, usesOnChanges: true, ngImport: i0, template: "\n\n@if (isLoading) {\n  <div class=\"loading\">\n    <ng-container *ngTemplateOutlet=\"loadingTemplate ? loadingTemplate : defaultLoading\"></ng-container>\n  </div>\n}\n@if (hasError) {\n  <div class=\"error\">\n    <ng-container *ngTemplateOutlet=\"errorTemplate ? errorTemplate : defaultError\"></ng-container>\n  </div>\n}\n\n<ng-template #defaultLoading><p>{{ getTextTranslated('loading') }}</p></ng-template>\n<ng-template #defaultError> <p>{{ errorMessage }}</p> </ng-template>\n\n<div [ngStyle]=\"{ border: borderCss }\">\n  <canvas id=\"canvas\"></canvas>\n</div>\n@if (!isLoading) {\n  <div class=\"toolbar\">\n    <div class=\"tools\">\n      <div class=\"row1\">\n        <i class=\"material-icons btn1\" [class.selected]=\"currentTool === 'brush'\" (click)=\"selectTool('brush')\"\n        [title]=\"getTooltipTranslated('tools.brush')\">brush</i>\n        @for (drawingSizeName of drawingSizesName; track drawingSizeName) {\n          <span class=\"size btn1\"\n            [style.width.px]=\"drawingSizes[drawingSizeName] * 0.8 + 8\"\n            [style.height.px]=\"drawingSizes[drawingSizeName] * 0.8 + 8\"\n            [style.borderRadius.px]=\"drawingSizes[drawingSizeName] * 0.4 + 4\"\n            [class.selected]=\"currentSize == drawingSizeName\"\n            [title]=\"getTooltipTranslated('sizes.' + drawingSizeName)\"\n            (click)=\"selectDrawingSize(drawingSizeName)\">\n          </span>\n        }\n        <input style=\"display: none\" type=\"file\" #fileInput (change)=\"importPhotoFromFile($event)\"\n          accept=\"image/*\"/>\n          @if (enableLoadAnotherImage && !hasImage) {\n            <i class=\"material-icons btn1\" (click)=\"fileInput.click();\"\n            [title]=\"getTooltipTranslated('loadImage')\">attach_file</i>\n          }\n          @if (enableLoadAnotherImage && !hasImage) {\n            <i class=\"material-icons btn1\" (click)=\"importPhotoFromUrl()\"\n            [title]=\"getTooltipTranslated('loadImageUrl')\">insert_drive_file</i>\n          }\n          @if (enableRemoveImage && hasImage) {\n            <i class=\"material-icons btn1\" (click)=\"removeImage()\"\n            [title]=\"getTooltipTranslated('removeImage')\">clear</i>\n          }\n          <i class=\"material-icons btn1\"  [class.selected]=\"currentTool === 'crop' || done===false\" (click)=\"crop()\"\n          [title]=\"getTooltipTranslated('crop')\">crop</i>\n          <i class=\"material-icons btn1\"  [class.selected]=\"currentTool === 'mask'\" (click)=\"maskC()\"\n          [title]=\"getTooltipTranslated('mask')\">crop_free</i>\n          <i class=\"material-icons btn1\" [class.selected]=\"currentTool === 'resize'\" (click)=\"resize()\"\n          [title]=\"getTooltipTranslated('resize')\">expand</i>\n          <i class=\"material-icons btn1\" [class.disabled]=\"!canUndo\" (click)=\"undo()\"\n          [title]=\"getTooltipTranslated('undo')\">undo</i>\n          <i class=\"material-icons btn1\" [class.disabled]=\"!canRedo\" (click)=\"redo()\"\n          [title]=\"getTooltipTranslated('redo')\">redo</i>\n          <!-- <i class=\"material-icons btn1\" (click)=\"clearCanvas()\" [title]=\"getTooltipTranslated('clear')\">delete</i> -->\n        </div>\n        <div class=\"row1\">\n          @for (shapeName of shapesNames; track shapeName) {\n            <div class=\"material-icons-outlined btn1\" (click)=\"shape(shapeName.shape)\">\n              {{shapeName.icon}}\n            </div>\n          }\n          <div class=\"material-icons btn1\" (click)=\"rotate(90)\">\n            rotate_right\n          </div>\n        </div>\n        <div class=\"row1\">\n          @for (colorName of colorsName; track colorName) {\n            <div [class.selected]=\"currentColor === colorName\" class=\"color\"\n              [ngClass]=\"colorName\"\n              [style.background]=\"colors[colorName]\" [title]=\"getTooltipTranslated('colors.' + colorName)\"\n              (click)=\"selectColor(colorName)\">\n            </div>\n          }\n        </div>\n      </div>\n      <!-- Any additional toolbar buttons to be projected by the consuming app -->\n      <ng-content></ng-content>\n    </div>\n  }\n  @if (!isLoading) {\n    <div class=\"buttons\">\n      @if (showCancelButton) {\n        <a href=\"#\" [class]=\"cancelBtnClass\"\n        (click)=\"cancelAction(); $event.preventDefault()\">{{ getTextTranslated('cancelBtn') }}</a>\n      }\n      <button  [class]=\"saveBtnClass\"\n      (click)=\"saveImage()\">{{ getTextTranslated('saveBtn') }}</button>\n    </div>\n  }\n", styles: [":host{display:flex;flex-direction:column;align-items:center}:host .toolbar{display:flex;flex-direction:column;justify-content:space-between;align-items:center}:host .tools{display:inline-flex;flex-direction:column;padding:20px;margin:10px;background:#fff;border-radius:6px;box-shadow:0 3px 10px #0006}:host .row1{display:flex;width:300px;justify-content:space-around;align-items:center;margin-bottom:10px}:host .row1:last-child{margin-bottom:0}:host .btn1{cursor:pointer}:host .btn1.selected{color:#bdbdbd}:host .btn1.disabled{cursor:initial;color:#bdbdbd}:host .size{background-color:#000}:host .size.selected{background-color:#bdbdbd}:host .color{width:28px;height:28px;border-radius:14px;cursor:pointer;display:flex;align-items:center;justify-content:center}:host .color.selected:after{content:\"\";width:10px;height:10px;background:#000;display:flex;border-radius:5px}:host .color.black{background-color:#000}:host .color.black.selected:after{background:#fff}:host .color.white{border:1px solid #a7a7a7}:host .buttons{width:80%;margin:10px;display:flex;flex-direction:row;justify-content:flex-end}:host .button{cursor:pointer;outline:0;border:none;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;min-width:64px;line-height:36px;padding:3px 16px;border-radius:4px;overflow:visible;transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow .28s cubic-bezier(.4,0,.2,1);margin:10px}:host .button:hover{text-decoration:none!important}:host .button.btn-primary{background-color:#ef5f27;color:#fff}:host .button.btn-primary:hover{background-color:#ef5f27cc}:host .button.btn-light{color:#ef5f27}:host .button.btn-light:hover{background-color:#ef5f271a}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageDrawingComponent, decorators: [{
            type: Component,
            args: [{ selector: 'image-drawing', standalone: true, imports: [NgTemplateOutlet, NgStyle, NgClass], template: "\n\n@if (isLoading) {\n  <div class=\"loading\">\n    <ng-container *ngTemplateOutlet=\"loadingTemplate ? loadingTemplate : defaultLoading\"></ng-container>\n  </div>\n}\n@if (hasError) {\n  <div class=\"error\">\n    <ng-container *ngTemplateOutlet=\"errorTemplate ? errorTemplate : defaultError\"></ng-container>\n  </div>\n}\n\n<ng-template #defaultLoading><p>{{ getTextTranslated('loading') }}</p></ng-template>\n<ng-template #defaultError> <p>{{ errorMessage }}</p> </ng-template>\n\n<div [ngStyle]=\"{ border: borderCss }\">\n  <canvas id=\"canvas\"></canvas>\n</div>\n@if (!isLoading) {\n  <div class=\"toolbar\">\n    <div class=\"tools\">\n      <div class=\"row1\">\n        <i class=\"material-icons btn1\" [class.selected]=\"currentTool === 'brush'\" (click)=\"selectTool('brush')\"\n        [title]=\"getTooltipTranslated('tools.brush')\">brush</i>\n        @for (drawingSizeName of drawingSizesName; track drawingSizeName) {\n          <span class=\"size btn1\"\n            [style.width.px]=\"drawingSizes[drawingSizeName] * 0.8 + 8\"\n            [style.height.px]=\"drawingSizes[drawingSizeName] * 0.8 + 8\"\n            [style.borderRadius.px]=\"drawingSizes[drawingSizeName] * 0.4 + 4\"\n            [class.selected]=\"currentSize == drawingSizeName\"\n            [title]=\"getTooltipTranslated('sizes.' + drawingSizeName)\"\n            (click)=\"selectDrawingSize(drawingSizeName)\">\n          </span>\n        }\n        <input style=\"display: none\" type=\"file\" #fileInput (change)=\"importPhotoFromFile($event)\"\n          accept=\"image/*\"/>\n          @if (enableLoadAnotherImage && !hasImage) {\n            <i class=\"material-icons btn1\" (click)=\"fileInput.click();\"\n            [title]=\"getTooltipTranslated('loadImage')\">attach_file</i>\n          }\n          @if (enableLoadAnotherImage && !hasImage) {\n            <i class=\"material-icons btn1\" (click)=\"importPhotoFromUrl()\"\n            [title]=\"getTooltipTranslated('loadImageUrl')\">insert_drive_file</i>\n          }\n          @if (enableRemoveImage && hasImage) {\n            <i class=\"material-icons btn1\" (click)=\"removeImage()\"\n            [title]=\"getTooltipTranslated('removeImage')\">clear</i>\n          }\n          <i class=\"material-icons btn1\"  [class.selected]=\"currentTool === 'crop' || done===false\" (click)=\"crop()\"\n          [title]=\"getTooltipTranslated('crop')\">crop</i>\n          <i class=\"material-icons btn1\"  [class.selected]=\"currentTool === 'mask'\" (click)=\"maskC()\"\n          [title]=\"getTooltipTranslated('mask')\">crop_free</i>\n          <i class=\"material-icons btn1\" [class.selected]=\"currentTool === 'resize'\" (click)=\"resize()\"\n          [title]=\"getTooltipTranslated('resize')\">expand</i>\n          <i class=\"material-icons btn1\" [class.disabled]=\"!canUndo\" (click)=\"undo()\"\n          [title]=\"getTooltipTranslated('undo')\">undo</i>\n          <i class=\"material-icons btn1\" [class.disabled]=\"!canRedo\" (click)=\"redo()\"\n          [title]=\"getTooltipTranslated('redo')\">redo</i>\n          <!-- <i class=\"material-icons btn1\" (click)=\"clearCanvas()\" [title]=\"getTooltipTranslated('clear')\">delete</i> -->\n        </div>\n        <div class=\"row1\">\n          @for (shapeName of shapesNames; track shapeName) {\n            <div class=\"material-icons-outlined btn1\" (click)=\"shape(shapeName.shape)\">\n              {{shapeName.icon}}\n            </div>\n          }\n          <div class=\"material-icons btn1\" (click)=\"rotate(90)\">\n            rotate_right\n          </div>\n        </div>\n        <div class=\"row1\">\n          @for (colorName of colorsName; track colorName) {\n            <div [class.selected]=\"currentColor === colorName\" class=\"color\"\n              [ngClass]=\"colorName\"\n              [style.background]=\"colors[colorName]\" [title]=\"getTooltipTranslated('colors.' + colorName)\"\n              (click)=\"selectColor(colorName)\">\n            </div>\n          }\n        </div>\n      </div>\n      <!-- Any additional toolbar buttons to be projected by the consuming app -->\n      <ng-content></ng-content>\n    </div>\n  }\n  @if (!isLoading) {\n    <div class=\"buttons\">\n      @if (showCancelButton) {\n        <a href=\"#\" [class]=\"cancelBtnClass\"\n        (click)=\"cancelAction(); $event.preventDefault()\">{{ getTextTranslated('cancelBtn') }}</a>\n      }\n      <button  [class]=\"saveBtnClass\"\n      (click)=\"saveImage()\">{{ getTextTranslated('saveBtn') }}</button>\n    </div>\n  }\n", styles: [":host{display:flex;flex-direction:column;align-items:center}:host .toolbar{display:flex;flex-direction:column;justify-content:space-between;align-items:center}:host .tools{display:inline-flex;flex-direction:column;padding:20px;margin:10px;background:#fff;border-radius:6px;box-shadow:0 3px 10px #0006}:host .row1{display:flex;width:300px;justify-content:space-around;align-items:center;margin-bottom:10px}:host .row1:last-child{margin-bottom:0}:host .btn1{cursor:pointer}:host .btn1.selected{color:#bdbdbd}:host .btn1.disabled{cursor:initial;color:#bdbdbd}:host .size{background-color:#000}:host .size.selected{background-color:#bdbdbd}:host .color{width:28px;height:28px;border-radius:14px;cursor:pointer;display:flex;align-items:center;justify-content:center}:host .color.selected:after{content:\"\";width:10px;height:10px;background:#000;display:flex;border-radius:5px}:host .color.black{background-color:#000}:host .color.black.selected:after{background:#fff}:host .color.white{border:1px solid #a7a7a7}:host .buttons{width:80%;margin:10px;display:flex;flex-direction:row;justify-content:flex-end}:host .button{cursor:pointer;outline:0;border:none;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;min-width:64px;line-height:36px;padding:3px 16px;border-radius:4px;overflow:visible;transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow .28s cubic-bezier(.4,0,.2,1);margin:10px}:host .button:hover{text-decoration:none!important}:host .button.btn-primary{background-color:#ef5f27;color:#fff}:host .button.btn-primary:hover{background-color:#ef5f27cc}:host .button.btn-light{color:#ef5f27}:host .button.btn-light:hover{background-color:#ef5f271a}\n"] }]
        }], ctorParameters: () => [{ type: i0.NgZone }], propDecorators: { src: [{
                type: Input
            }], width: [{
                type: Input
            }], height: [{
                type: Input
            }], saveBtnClass: [{
                type: Input
            }], cancelBtnClass: [{
                type: Input
            }], forceSizeCanvas: [{
                type: Input
            }], forceSizeExport: [{
                type: Input
            }], enableRemoveImage: [{
                type: Input
            }], enableLoadAnotherImage: [{
                type: Input
            }], enableTooltip: [{
                type: Input
            }], showCancelButton: [{
                type: Input
            }], i18nUser: [{
                type: Input,
                args: ['i18n']
            }], locale: [{
                type: Input
            }], saveBtnText: [{
                type: Input
            }], cancelBtnText: [{
                type: Input
            }], loadingText: [{
                type: Input
            }], errorText: [{
                type: Input
            }], loadingTemplate: [{
                type: Input
            }], errorTemplate: [{
                type: Input
            }], outputMimeType: [{
                type: Input
            }], outputQuality: [{
                type: Input
            }], borderCss: [{
                type: Input
            }], drawingSizes: [{
                type: Input
            }], colors: [{
                type: Input
            }], save: [{
                type: Output
            }], cancel: [{
                type: Output
            }] } });

class ImageDrawingModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageDrawingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: ImageDrawingModule, imports: [CommonModule,
            MatIconModule,
            ImageDrawingComponent], exports: [ImageDrawingComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageDrawingModule, imports: [CommonModule,
            MatIconModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageDrawingModule, decorators: [{
            type: NgModule,
            args: [{
                    exports: [
                        ImageDrawingComponent,
                    ],
                    imports: [
                        CommonModule,
                        MatIconModule,
                        ImageDrawingComponent
                    ]
                }]
        }] });

/*
 * Public API Surface of ngx-image-drawing-zone
 */

/**
 * Generated bundle index. Do not edit.
 */

export { I18nEn, I18nFr, I18nHe, ImageDrawingComponent, ImageDrawingModule, i18nLanguages };
//# sourceMappingURL=ngx-image-drawing-zone.mjs.map