在一个有角度的应用程序中,我使用Fabric.js实现了一个简单的白板,该白板使用户可以绘制一些基本形状和徒手画图。形状是空的,充满了圆形和矩形,还有一个基本的UML图模板,这两个模板相互重叠。
当我选择一个或多个对象时,矩形和圆的所有实例的位置都会自动转换为画布的原点,只是将选择标记保留在其原始位置。奇怪的是,UML模板不会发生这种情况,它最终还由两个简单的rect组成,就像一个变压器,除了另一个初始大小。内置功能的徒手图也不在乎。
单独选择此元素时,它们将保持在“位置”。我没有覆盖任何选择方法。
值得一提的是,白板位于应用程序内的小部件中,这意味着您可以在显示器周围拖动白板,因此可以使用值adjustedX
和adjustedY
。但是,这些对象总是转换为原点,其他对象也可以正常工作,因此我倾向于将其排除在外。
单选
组选择:所有选中的对象
组选择:仅选择矩形
这是创建我的画布和两个形状的代码
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
在应用程序中更改为“选择模式”时被激活。
答案 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);
}