Fabric.js: Group-Selection 将某些对象的中心位置转换为 canvas 原点

Fabric.js: Group-Selection transforms certain objects' center position to canvas origin

在一个 angular 应用程序中,我用 Fabric.js 实现了一个简单的白板,它可以让用户绘制一些基本形状和手绘图。形状是空白和填充的圆形和矩形,以及一个基本的 UML 图模板,它们是两个彼此重叠的单个矩形。

当我select一个或多个对象时,所有矩形和圆实例的位置自动转换到canvas'原点,只留下select离子标记在原来的位置。奇怪的是,这不会发生在 UML 模板中,它最终也由两个简单的矩形组成,就像变换器一样,除了另一个初始大小。内置功能的徒手画也不在乎。

当这些元素被单独 select 编辑时,它们仍然是 "in position"。我没有覆盖任何 selection 方法。

值得一提的是,白板位于应用程序内的一个小部件中,这意味着您可以在显示屏周围拖动白板,因此值 adjustedXadjustedY。但是,物体总是变换到原点,其他物体正常工作,所以我倾向于排除。

单select离子

组select离子:所有对象selected

组select离子:仅矩形selected

这是创建我的 canvas 和两个形状

的代码
        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在应用程序中更改为"selection mode"时激活。

所以我无法真正找到这种行为的原因,但找到了 work-around。

删除对象时,我只是克隆这个元素,删除原始元素并删除克隆的元素,结果对象不再变形。

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);
    }