TypeError:“ instance [methodName]不是函数”-Fabric JS错误

时间:2018-06-28 09:56:33

标签: javascript angular typescript fabricjs

我试图用该线将画布上的两个图形连接起来,并且该线将固定在图形上,因此图形在画布上移动的位置相应的箭头也会移动。

它的工作方式与我期望的相同,但是在我通过调用方法"rasterizeJSON()"生成JSON时却给了我错误,它在应用JSON.stringify(objectName);时没有将对象更改为字符串< / p>

  

错误-TypeError:“ instance [methodName]不是函数”   _toObjectwebpack-

export class WorkFlowEditorComponent {

@ViewChild('launch') launch: ElementRef;

REC_WIDTH = 60;
REC_HEIGHT = 30;
TRI_WIDTH = 10;
TRI_HEIGHT = 10;
disX;
disY;
_self = this;
start;
private canvas: any;
private props: any = {
    canvasFill: '#ffffff',
    canvasImage: '',
    id: null,
    name: null,
    opacity: null,
    fill: null,
    fontSize: null,
    lineHeight: null,
    charSpacing: null,
    fontWeight: null,
    fontStyle: null,
    textAlign: null,
    fontFamily: null,
    TextDecoration: ''
};

private textString: string;
private url: string = '';
private size: any = {
    width: 1000,
    height: 400
};

private json: any;
private globalEditor: boolean = false;
private textEditor: boolean = false;
private imageEditor: boolean = false;
private figureEditor: boolean = false;
private selected: any;

constructor() { }

ngOnInit() {
    //   ['object:moving'].forEach(this.addChildMoveLine);
    //setup front side canvas
    this.canvas = new fabric.Canvas('canvas', {
        hoverCursor: 'pointer',
        selection: true,
        selectionBorderColor: 'blue'
    });


    var HideControls = {
        'tl': true,
        'tr': false,
        'bl': true,
        'br': true,
        'ml': true,
        'mt': true,
        'mr': true,
        'mb': true,
        'mtr': true
    };

    this.canvas.on({
        'object:moving': (e) => {
            this.addChildMoveLine(e);
            //console.log(e);
            //this.addDeleteBtn(e.target.oCoords.tr.x, e.target.oCoords.tr.y);
        },
        'object:modified': (e) => {
            //console.log("object modified");
            this.addDeleteBtn(e.target.oCoords.tr.x, e.target.oCoords.tr.y);
        },
        'object:selected': (e) => {
            // console.log("inside canvas selected");
            this.addChildMoveLine(e);
            this.addDeleteBtn(e.target.oCoords.tr.x, e.target.oCoords.tr.y);
            let selectedObject = e.target;
            console.log("printing selected object" + selectedObject);
            this.selected = selectedObject
            selectedObject.hasRotatingPoint = true;
            selectedObject.transparentCorners = false;

            // selectedObject.cornerColor = 'rgba(255, 87, 34, 0.7)';

            this.resetPanels();

            if (selectedObject.type !== 'group' && selectedObject) {

                this.getId();
                this.getOpacity();

                switch (selectedObject.type) {
                    case 'rect':
                    case 'circle':
                    case 'triangle':
                        this.figureEditor = true;
                        this.getFill();
                        break;
                    case 'i-text':
                        this.textEditor = true;
                        this.getLineHeight();
                        this.getCharSpacing();
                        this.getBold();
                        this.getFontStyle();
                        this.getFill();
                        this.getTextDecoration();
                        this.getTextAlign();
                        this.getFontFamily();
                        break;
                    case 'image':
                        console.log('image');
                        break;
                }
            }
        },
        'selection:cleared': (e) => {
            this.selected = null;
            this.resetPanels();
        }
    });

    this.canvas.setWidth(this.size.width);
    this.canvas.setHeight(this.size.height);

    // get references to the html canvas element & its context
    // this.canvas.on('mouse:down', (e) => {
    // let canvasElement: any = document.getElementById('canvas');
    // console.log(canvasElement)
    // });

}

//method to connect arrow from one shape to another
addChild() {
    if (this.canvas.getActiveObject() == null) {
        console.log("inside add child if");
        return "getactiveobject is null (add child)";
    }
    this.canvas.addChild = {
        start: this.canvas.getActiveObject()
    };

    //for when addChild is clicked twice
    this.canvas.off({
        'object:selected': (e) => {
            this.addChildLine(e)
            console.log("move off" + e);
            //this.addDeleteBtn(e.target.oCoords.tr.x, e.target.oCoords.tr.y);
        },
    })

    this.canvas.on({
        'object:selected': (e) => {
            this.addChildLine(e)
            console.log("move line");
        },
    }
    );
}

calcArrowAngle(x1, y1, x2, y2) {
    var angle = 0,
        x, y;

    console.log("arrow angle", x1, y1, x2, y2);
    x = (x2 - x1);
    y = (y2 - y1);

    if (x === 0) {
        angle = (y === 0) ? 0 : (y > 0) ? Math.PI / 2 : Math.PI * 3 / 2;
    } else if (y === 0) {
        angle = (x > 0) ? 0 : Math.PI;
    } else {
        angle = (x < 0) ? Math.atan(y / x) + Math.PI : (y < 0) ? Math.atan(y / x) + (2 * Math.PI) : Math.atan(y / x);
    }

    console.log("PI", Math.PI);
    return (angle * 180 / Math.PI + 90);
}

addChildLine(options) {
    this.canvas.off({
        'object:selected': (e) => {
            this.addChildLine(e)
            console.log("move line in off");
            //this.addDeleteBtn(e.target.oCoords.tr.x, e.target.oCoords.tr.y);
        },
    }
    )

    var fromObject = this.canvas.addChild.start;
    console.log(fromObject);
    var toObject = options.target;
    console.log(toObject);
    var from = fromObject.getCenterPoint();
    // console.log(from)
    var to = toObject.getCenterPoint();
    var fromX = from.x;
    var fromY = from.y;
    var toX = to.x;
    var toY = to.y;

    // var disX = REC_WIDTH/2 + TRI_WIDTH/2;
    // var disY = REC_HEIGHT/2 + TRI_HEIGHT/2;
    //var distanceX, distanceY;
    //calibrateLine(fromX, fromY, toX, toY);

    var calibrateX = this.REC_WIDTH / 2 + this.TRI_WIDTH / 2;
    var calibrateY = this.REC_HEIGHT / 2 + this.TRI_HEIGHT / 2

    //storing and calculate x and y axis of the imagrd to be connected
    var distanceX, distanceY;

    if (fromX < toX) {
        distanceX = toX - fromX;
    } else {
        distanceX = fromX - toX;
    }

    if (fromY < toY) {
        distanceY = toY - fromY;
    } else {
        distanceY = fromY - toY;
    }

    if (distanceX > distanceY) {

        if (fromX < toX) {
            toX -= calibrateX;
        } else {
            toX += calibrateX;
        }
    } else {
        if (fromY < toY) {
            toY -= calibrateY;
        } else {
            toY += calibrateY;
        }
    }

    var line = new fabric.Line([fromX, fromY, toX, toY], {
        fill: 'red',
        stroke: 'red',
        strokeWidth: 1,
        selectable: false,
        fromObject: fromObject,
        toObject: toObject,
    });

    // leftover code that we might need but probably not
    /*
    centerX = (from.x + to.x)/2;
    centerY = (from.y + to.y)/2;
    deltaX = line.left - centerX;
    deltaY = line.top - centerY;
    */
    console.log(line.x1)
    line.triangle = new fabric.Triangle({
        left: line.x2,
        top: line.y2,
        angle: this.calcArrowAngle(line.x1, line.y1, line.x2, line.y2),
        originX: 'center',
        originY: 'center',
        hasBorders: false,
        hasControls: false,
        lockScalingX: true,
        lockScalingY: true,
        lockRotation: true,
        pointType: 'arrow_start',
        width: this.TRI_WIDTH,
        height: this.TRI_HEIGHT,
        fill: 'red',
        selectable: false,
    });



    var Group = new fabric.Group([line, line.triangle]);
    // canvas.add(Group);
    var objs = [line, line.triangle];

    var add = new fabric.Group(objs);
    // this.extend(add, this.randomId());
    this.canvas.add(line, line.triangle);


    //this.canvas.add(add);
    //this.selectItemAfterAdded(add);
    //this.canvas.add(Group);
    // so that the line is behind the connected shapes
    line.sendToBack();

    // add a reference to the line to each object
    //console.log(fromObject.addChild);
    fromObject.addChild = fromObject.addChild || {};
    fromObject.addChild.lines = fromObject.addChild.lines || [];
    console.log(fromObject.addChild.lines);
    fromObject.addChild.lines.push(line);
    toObject.addChild = toObject.addChild || {};
    //console.log(toObject.addChild);
    toObject.addChild.lines = toObject.addChild.lines || [];
    console.log(toObject.addChild.lines);
    toObject.addChild.lines.push(line);

    // to remove line references when the line gets removed
    line.addChildRemove = function () {
        fromObject.addChild.lines.forEach(function (e, i, arr) {
            if (e === line)
                arr.splice(i, 1);
        });
    };

    // undefined instead of delete since we are anyway going to do this many times
    this.canvas.addChild = undefined;
}

addChildMoveLine(e) {
    var self = this;
    //console.log("inside child move line");
    // this.canvas.on({
    //     'object:moving': (e) => {
    // console.log("move");
    // console.log(e.target);

    // this.canvas.on(event, function(options) {
    var object = e.target;
    // console.log("addChildMoveLine");
    // udpate lines (if any)
    if (object.addChild && object.addChild.lines) {
        object.addChild.lines.forEach(function (line) {
            console.log(line.fromObject.getCenterPoint());
            var fcenter = line.fromObject.getCenterPoint(),
                fx = fcenter.x,
                fy = fcenter.y,
                tcenter = line.toObject.getCenterPoint(),
                tx = tcenter.x,
                ty = tcenter.y,
                xdis = self.REC_WIDTH / 2 + self.TRI_WIDTH / 2,
                ydis = self.REC_HEIGHT / 2 + self.TRI_HEIGHT / 2,
                horizontal = Math.abs(tx - line.x1) > Math.abs(ty - line.y1)
            line.set({
                'x1': fx,
                'y1': fy,
                'x2': tx + xdis * (horizontal ? (tx < line.x1 ? 1 : -1) : 0),
                'y2': ty + ydis * (horizontal ? 0 : (ty < line.y1 ? 1 : -1)),
            });
            //this.calcArrowAngle(line.x1, line.y1, line.x2, line.y2)
            line.triangle.set({
                'left': line.x2, 'top': line.y2,
                'angle': self.calcArrowAngle(line.x1, line.y1, line.x2, line.y2)
            });
        });
    }

    this.canvas.renderAll();

}

calibrateLine(fromX, fromY, toX, toY) {

    var distanceX = 0;
    var distanceY = 0;

    // if (fromX < toX) {
    //     distanceX = toX - fromX;
    // } else {
    //     distanceX = fromX - toX;
    // }

    // if (fromY < toY) {
    //     distanceY = toY - fromY;
    // } else {
    //     distanceY = fromY - toY;
    // }

    if (distanceX > distanceY) {

        if (fromX < toX) {
            toX -= this.disX;
        } else {
            toX += this.disX;
        }
    } else {
        if (fromY < toY) {
            toY -= this.disY;
        } else {
            toY += this.disY;
        }
    }
}

addDeleteBtn(x, y) {
    $(".deleteBtn").remove();
    var btnLeft = x - 10;
    var btnTop = y - 10;
    // <button data-toggle="tooltip" data-placement="bottom" title="Delete element" type="button" class="btn btn-outline-danger"
    //                     [disabled]="!selected" (click)="removeSelected();">

    //                 </button>
    var deleteBtn = ' <i class="fa fa-trash deleteBtn" aria-hidden="true" style="position:absolute;top:' + btnTop + 'px;left:' + btnLeft + 'px;cursor:pointer;width:20px;height:20px; " onclick=alert("hrllo")></i>';
    $(".canvas-container").append(deleteBtn);
}


/*------------------------Block elements------------------------*/

//Block "Size"

changeSize(event: any) {
    console.log("changeSize")
    this.canvas.setWidth(this.size.width);
    this.canvas.setHeight(this.size.height);
}

//Block "Add text"

addText() {
    let textString = this.textString;
    let text = new fabric.IText(textString, {
        left: 10,
        top: 10,
        fontFamily: 'helvetica',
        angle: 0,
        fill: '#000000',
        scaleX: 0.5,
        scaleY: 0.5,
        fontWeight: '',
        hasRotatingPoint: true
    });
    this.extend(text, this.randomId());
    this.canvas.add(text);
    this.selectItemAfterAdded(text);
    this.textString = '';
}

//Block "Add images"

getImgPolaroid(event: any, src: any) {
    console.log("inside polaroid method");
    let el = event.target;

    console.log(src);
    fabric.Image.fromURL(src, (image) => {
        image.set({
            left: 10,
            top: 10,
            angle: 0,
            padding: 10,
            cornersize: 10,
            //hasRotatingPoint: true,
            peloas: 12,
            hasControls: false
        });
        image.setWidth(50);
        image.setHeight(50);
        this.extend(image, this.randomId());
        this.canvas.add(image);
        this.selectItemAfterAdded(image);
    });
}

//Block "Upload Image"

addImageOnCanvas(url) {
    if (url) {
        fabric.Image.fromURL(url, (image) => {
            image.set({
                left: 10,
                top: 10,
                angle: 0,
                padding: 10,
                cornersize: 10,
                hasRotatingPoint: true
            });
            image.setWidth(200);
            image.setHeight(200);
            this.extend(image, this.randomId());
            this.canvas.add(image);
            this.selectItemAfterAdded(image);
        });
    }
}

readUrl(event) {
    if (event.target.files && event.target.files[0]) {
        var reader = new FileReader();
        reader.onload = (event) => {
            this.url = event.target['result'];
        }
        reader.readAsDataURL(event.target.files[0]);
    }
}

removeWhite(url) {
    this.url = '';
};

//Block "Add figure"

addFigure(figure) {
    let add: any;
    switch (figure) {
        case 'rectangle':
            add = new fabric.Rect({
                width: 60, height: 30, left: 100, top: 100, angle: 0,
                fill: '#ffffff',
                stroke: 'black',
                strokeWidth: 1,
                hasControls: false
            });
            break;
        case 'square':
            add = new fabric.Rect({
                width: 50, height: 50, left: 10, top: 10, angle: 0,
                fill: '#ffffff',
                stroke: 'black',
                strokeWidth: 1,
                hasControls: false
            });
            break;
        case 'triangle':
            add = new fabric.Rect({
                left: 100, top: 100, width: 20, height: 20, angle: 45,

                fill: '#ffffff',
                stroke: 'black',
                strokeWidth: 1,
                hasControls: false
            });
            break;
        case 'circle':
            add = new fabric.Circle({
                radius: 20, left: 10, top: 10,
                fill: '#ffffff',
                stroke: 'black',
                strokeWidth: 1,
                hasControls: false
            });
            break;
        case 'line':
            var triangle = new fabric.Triangle({
                width: 10,
                height: 15,
                fill: 'red',
                left: 235,
                top: 65,
                angle: 90
            });

            var line = new fabric.Line([50, 100, 200, 100], {
                left: 75,
                top: 70,
                stroke: 'red'
            });
            var objs = [line, triangle];

            add = new fabric.Group(objs);
            break;

    }
    this.extend(add, this.randomId());
    this.canvas.add(add);
    this.selectItemAfterAdded(add);
}

/*Canvas*/

cleanSelect() {
    this.canvas.deactivateAllWithDispatch().renderAll();
}

selectItemAfterAdded(obj) {

    this.canvas.deactivateAllWithDispatch().renderAll();
    this.canvas.setActiveObject(obj);
}

setCanvasFill() {

    if (!this.props.canvasImage) {
        this.canvas.backgroundColor = this.props.canvasFill;
        this.canvas.renderAll();
    }
}

extend(obj, id) {

    obj.toObject = (function (toObject) {
        return function () {
            return fabric.util.object.extend(toObject.call(this), {
                id: id,
                name: name
            });
        };
    })(obj.toObject);
}

setCanvasImage() {
    console.log("setCanvasImage");
    let self = this;
    if (this.props.canvasImage) {
        this.canvas.setBackgroundColor({ source: this.props.canvasImage, repeat: 'repeat' }, function () {
            // self.props.canvasFill = '';
            self.canvas.renderAll();
        });
    }
}

randomId() {
    return Math.floor(Math.random() * 999999) + 1;
}

/*------------------------Global actions for element------------------------*/

getActiveStyle(styleName, object) {

    object = object || this.canvas.getActiveObject();
    if (!object) return '';

    return (object.getSelectionStyles && object.isEditing)
        ? (object.getSelectionStyles()[styleName] || '')
        : (object[styleName] || '');
}


setActiveStyle(styleName, value, object) {

    object = object || this.canvas.getActiveObject();
    if (!object) return;

    if (object.setSelectionStyles && object.isEditing) {
        var style = {};
        style[styleName] = value;
        object.setSelectionStyles(style);
        object.setCoords();
    }
    else {
        object.set(styleName, value);
    }

    object.setCoords();
    this.canvas.renderAll();
}


getActiveProp(name) {

    var object = this.canvas.getActiveObject();
    if (!object) return '';

    return object[name] || '';
}

setActiveProp(name, value) {

    var object = this.canvas.getActiveObject();
    if (!object) return;
    object.set(name, value).setCoords();
    this.canvas.renderAll();
}

clone() {
    let activeObject = this.canvas.getActiveObject(),
        activeGroup = this.canvas.getActiveGroup();

    if (activeObject) {
        let clone;
        switch (activeObject.type) {
            case 'rect':
                clone = new fabric.Rect(activeObject.toObject());
                break;
            case 'circle':
                clone = new fabric.Circle(activeObject.toObject());
                break;
            case 'triangle':
                clone = new fabric.Triangle(activeObject.toObject());
                break;
            case 'i-text':
                clone = new fabric.IText('', activeObject.toObject());
                break;
            case 'image':
                clone = fabric.util.object.clone(activeObject);
                break;
        }
        if (clone) {
            clone.set({ left: 10, top: 10 });
            this.canvas.add(clone);
            this.selectItemAfterAdded(clone);
        }
    }
}

getId() {
    //console.log("getId");
    this.props.id = this.canvas.getActiveObject().toObject().id;
}

setId() {
    console.log("setId");
    let val = this.props.id;
    let complete = this.canvas.getActiveObject().toObject();
    console.log(complete);
    this.canvas.getActiveObject().toObject = () => {
        complete.id = val;
        return complete;
    };
}

setName() {
    console.log("setName");
    let val = this.props.name;
    let complete = this.canvas.getActiveObject().toObject();
    console.log(complete);
    this.canvas.getActiveObject().toObject = () => {
        complete.name = val;
        return complete;
    };
}

getOpacity() {
    this.props.opacity = this.getActiveStyle('opacity', null) * 100;
}

setOpacity() {
    this.setActiveStyle('opacity', parseInt(this.props.opacity) / 100, null);
}

getFill() {
    this.props.fill = this.getActiveStyle('fill', null);
}

setFill() {
    this.setActiveStyle('fill', this.props.fill, null);
}

getLineHeight() {
    console.log("getLineHeight");
    this.props.lineHeight = this.getActiveStyle('lineHeight', null);
}

setLineHeight() {
    this.setActiveStyle('lineHeight', parseFloat(this.props.lineHeight), null);
}

getCharSpacing() {
    this.props.charSpacing = this.getActiveStyle('charSpacing', null);
}

setCharSpacing() {
    this.setActiveStyle('charSpacing', this.props.charSpacing, null);
}

getFontSize() {
    this.props.fontSize = this.getActiveStyle('fontSize', null);
}

setFontSize() {
    this.setActiveStyle('fontSize', parseInt(this.props.fontSize), null);
}

getBold() {
    this.props.fontWeight = this.getActiveStyle('fontWeight', null);
}

setBold() {
    this.props.fontWeight = !this.props.fontWeight;
    this.setActiveStyle('fontWeight', this.props.fontWeight ? 'bold' : '', null);
}

getFontStyle() {
    this.props.fontStyle = this.getActiveStyle('fontStyle', null);
}

setFontStyle() {
    this.props.fontStyle = !this.props.fontStyle;
    this.setActiveStyle('fontStyle', this.props.fontStyle ? 'italic' : '', null);
}


getTextDecoration() {
    this.props.TextDecoration = this.getActiveStyle('textDecoration', null);
}

setTextDecoration(value) {
    let iclass = this.props.TextDecoration;
    if (iclass.includes(value)) {
        iclass = iclass.replace(RegExp(value, "g"), "");
    } else {
        iclass += ` ${value}`
    }
    this.props.TextDecoration = iclass;
    this.setActiveStyle('textDecoration', this.props.TextDecoration, null);
}

hasTextDecoration(value) {
    return this.props.TextDecoration.includes(value);
}


getTextAlign() {
    this.props.textAlign = this.getActiveProp('textAlign');
}

setTextAlign(value) {
    this.props.textAlign = value;
    this.setActiveProp('textAlign', this.props.textAlign);
}

getFontFamily() {
    this.props.fontFamily = this.getActiveProp('fontFamily');
}

setFontFamily() {
    this.setActiveProp('fontFamily', this.props.fontFamily);
}

/*System*/


removeSelected() {
    console.log("removeSelected");
    let activeObject = this.canvas.getActiveObject(),
        activeGroup = this.canvas.getActiveGroup();

    if (activeObject) {
        this.canvas.remove(activeObject);
        // this.textString = '';
    }
    else if (activeGroup) {
        let objectsInGroup = activeGroup.getObjects();
        this.canvas.discardActiveGroup();
        let self = this;
        objectsInGroup.forEach(function (object) {
            self.canvas.remove(object);
        });
    }
}

bringToFront() {
    console.log("bringToFront");
    let activeObject = this.canvas.getActiveObject(),
        activeGroup = this.canvas.getActiveGroup();

    if (activeObject) {
        activeObject.bringToFront();
        // activeObject.opacity = 1;
    }
    else if (activeGroup) {
        let objectsInGroup = activeGroup.getObjects();
        this.canvas.discardActiveGroup();
        objectsInGroup.forEach((object) => {
            object.bringToFront();
        });
    }
}

sendToBack() {

    let activeObject = this.canvas.getActiveObject(),
        activeGroup = this.canvas.getActiveGroup();

    if (activeObject) {
        activeObject.sendToBack();
        // activeObject.opacity = 1;
    }
    else if (activeGroup) {
        let objectsInGroup = activeGroup.getObjects();
        this.canvas.discardActiveGroup();
        objectsInGroup.forEach((object) => {
            object.sendToBack();
        });
    }
}

confirmClear() {
    console.log("confirmClear");
    if (confirm('Are you sure?')) {
        this.canvas.clear();
    }
}

rasterize() {
    console.log("rasterize");
    if (!fabric.Canvas.supports('toDataURL')) {
        alert('This browser doesn\'t provide means to serialize canvas to an image');
    }
    else {
        console.log(this.canvas.toDataURL('png'))
        //window.open(this.canvas.toDataURL('png'));
        var image = new Image();
        image.src = this.canvas.toDataURL('png')
        var w = window.open("");
        w.document.write(image.outerHTML);
    }
}

rasterizeSVG() {
    console.log("rasterizeSVG");
    console.log(this.canvas.toSVG())
    // window.open(
    //   'data:image/svg+xml;utf8,' +
    //   encodeURIComponent(this.canvas.toSVG()));
    // console.log(this.canvas.toSVG())
    // var image = new Image();
    // image.src = this.canvas.toSVG()
    var w = window.open("");
    w.document.write(this.canvas.toSVG());
};


saveCanvasToJSON() {
    let json = JSON.stringify(this.canvas);
    localStorage.setItem('Kanvas', json);
    console.log('json');
    console.log(json);

}

loadCanvasFromJSON() {
    let CANVAS = localStorage.getItem('Kanvas');
    console.log('CANVAS');
    console.log(CANVAS);

    // and load everything from the same json
    this.canvas.loadFromJSON(CANVAS, () => {
        console.log('CANVAS untar');
        console.log(CANVAS);

        // making sure to render canvas at the end
        this.canvas.renderAll();

        // and checking if object's "name" is preserved
        console.log('this.canvas.item(0).name');
        console.log(this.canvas);
    });

};

rasterizeJSON() {
    console.log("inside rasterize json method");
    console.log(this.canvas);
    try {
        this.json = JSON.stringify(this.canvas);
    }
    catch (error) {
        console.log(error);
    }
    //below line used for storing json locally on browser
    localStorage.setItem("Kanvas", this.json);
}

resetPanels() {
    console.log("resetPanels");

    // this.launch.nativeElement.click();
    this.textEditor = false;
    this.imageEditor = false;
    this.figureEditor = false;
  }
}

0 个答案:

没有答案