Fabric.js:组选择将某些对象的中心位置转换为画布原点

时间:2019-04-24 12:39:30

标签: angular fabricjs selection

在一个有角度的应用程序中,我使用Fabric.js实现了一个简单的白板,该白板使用户可以绘制一些基本形状和徒手画图。形状是空的,充满了圆形和矩形,还有一个基本的UML图模板,这两个模板相互重叠。

当我选择一个或多个对象时,矩形和圆的所有实例的位置都会自动转换为画布的原点,只是将选择标记保留在其原始位置。奇怪的是,UML模板不会发生这种情况,它最终还由两个简单的rect组成,就像一个变压器,除了另一个初始大小。内置功能的徒手图也不在乎。

单独选择此元素时,它们将保持在“位置”。我没有覆盖任何选择方法。

值得一提的是,白板位于应用程序内的小部件中,这意味着您可以在显示器周围拖动白板,因此可以使用值adjustedXadjustedY。但是,这些对象总是转换为原点,其他对象也可以正常工作,因此我倾向于将其排除在外。

单选

enter image description here

组选择:所有选中的对象

enter image description here

组选择:仅选择矩形

enter image description here

这是创建我的画布和两个形状的代码

        const component = this;
        this.canvas = new fabric.Canvas('myCanvas', {
            selectionColor: 'rgba(0, 0, 255, 0.1)',
            selectionLineWidth: 2,
            selection: false,
            preserveObjectStacking: true,

        });
        this.canvas.isDrawingMode = true;
        this.canvas.freeDrawingBrush.width = 5;
        this.canvas.setHeight(window.innerHeight);
        this.canvas.setWidth(window.innerWidth);
        $(window).on('resize', function(){
            component.canvas.setHeight(window.innerHeight);
            component.canvas.setWidth(window.innerWidth);
        });
        this.setObjectsSelectable(false);


        if(this.canvas){
            // omitted variable declarations

            $(".upper-canvas")
                .on('mousedown touchstart',function(e){
                    isDown = true;
                    // ...

                    switch(component.drawingMode){
                        case DrawingMode.UML:
                            var rectTop = new fabric.Rect({
                                width: 1,
                                height: 1,
                                left: anchorX,
                                top: anchorY,
                                stroke: component.color,
                                strokeWidth: component.stroke,
                                fill: '',
                                selectable: false
                            });
                            var rectBottom = new fabric.Rect({
                                width: 1,
                                height: 1,
                                left: anchorX,
                                top: anchorY,
                                stroke: component.color,
                                strokeWidth: component.stroke,
                                fill: '',
                                selectable: false
                            });
                            component.canvas.add(rectTop);
                            component.canvas.add(rectBottom);
                            umlObjectTop = rectTop;
                            umlObjectBottom = rectBottom;
                            break;
                        case DrawingMode.SHAPE:
                            var rect = new fabric.Rect({
                                width: 5,
                                height: 5,
                                left: anchorX,
                                top: anchorY,
                                stroke: component.color,
                                strokeWidth: component.stroke,
                                fill: component.fill,
                                selectable: false
                            });
                            component.canvas.add(rect);
                            drawingObject = rect;
                            break;
                        case DrawingMode.CIRCLE:
                            // ...
                            break;
                    }
                })
                .on('mousemove touchmove', function(e){
                    // ...

                    switch(component.drawingMode){

                        case DrawingMode.UML:

                            if(!isDown) return;

                            // ...

                            if(heightTop > 100){
                                heightTop = 100;
                                heightBottom = component.abs(anchorY - adjustedY) - 160;
                            }
                            if(anchorX > adjustedX){
                                umlObjectTop.set({ left: component.abs(adjustedX) });
                                umlObjectBottom.set({ left: component.abs(adjustedX) });
                            }
                            if(anchorY > adjustedY){
                                umlObjectTop.set({ top: component.abs(adjustedY) });
                                umlObjectBottom.set({ top: component.abs(adjustedY)+heightTop });
                            }

                            umlObjectTop.set({ width: widthT });
                            umlObjectTop.set({ height: heightTop });
                            umlObjectBottom.set({ width: widthT });
                            umlObjectBottom.set({ height: heightBottom });
                            component.canvas.renderAll();
                            break;
                        case DrawingMode.SHAPE:
                            if(!isDown) return;
                            if(anchorX > adjustedX){
                                drawingObject.set({ left: component.abs(adjustedX) });
                            }
                            if(anchorY > adjustedY){
                                drawingObject.set({ top: component.abs(adjustedY) });
                            }

                            drawingObject.set({ width: component.abs(anchorX - adjustedX) });
                            drawingObject.set({ height: component.abs(anchorY - adjustedY) });
                            component.canvas.renderAll();
                            break;

                        case DrawingMode.CIRCLE:
                            // ...
                            break;
                    }
                })
                .on('mouseup touchend', function(e){
                    isDown = false;

                    switch(component.drawingMode){
                        case DrawingMode.SHAPE:
                        case DrawingMode.CIRCLE:
                            component.canvas.add(drawingObject);
                            break;
                    }
                });
        }

注意:selection = false在应用程序中更改为“选择模式”时被激活。

1 个答案:

答案 0 :(得分:0)

因此,我真的无法找到造成这种现象的原因,但找到了解决方法。

在放置对象时,我只是克隆此元素,删除原始元素,然后删除克隆的元素,然后tadaaa,对象不再变形。

dropObject(drawingObject: any, id: number, awtype: string) {
        const component = this;
        drawingObject.clone(function (clone) {
            clone.set('selectable', false);
            component.addLongClickListener(clone);
            clone.toObject = (function (toObject) {
                return function () {
                    return fabric.util.object.extend(toObject.call(this), {
                        id: this.id,
                        awtype: this.awtype
                    });
                };
            })(clone.toObject);
            clone.id = id;
            clone.awtype = awtype;
            component.canvas.add(clone);
            component.canvas.renderAll();
        });
        this.canvas.remove(drawingObject);
    }