angular - Fabric.js:组选择将某些对象的中心位置转换为画布原点
问题描述
在一个 Angular 应用程序中,我使用 Fabric.js 实现了一个简单的白板,它可以让用户绘制一些基本的形状和手绘。这些形状是空的,填充的圆形和矩形,以及一个基本的 UML 图模板,它们是两个相互重叠的单个矩形。
当我选择一个或多个对象时,所有矩形和圆形实例的位置都会自动转换到画布的原点,只将选择标记留在其原始位置。奇怪的是,UML 模板不会发生这种情况,它最终也由两个简单的矩形组成,就像转换器一样,除了另一个初始大小。内置功能的手绘图也不在意。
当这些元素被单独选择时,它们保持“就位”。我没有覆盖任何选择方法。
值得一提的是,白板位于应用程序内的小部件中,这意味着您可以将白板拖动到显示屏周围,因此值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
在应用程序中更改为“选择模式”时会被激活。
解决方案
所以我并没有真正找到这种行为的原因,但找到了一种解决方法。
删除对象时,我只是克隆此元素,删除原始元素并删除克隆的元素,然后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);
}
推荐阅读
- amazon-web-services - 如何通过 AWS HTTP API 向 Lambda 发送参数
- mysql - MySQL 奇怪的符号
- python - Python如何编程在一定时间后关闭
- flutter - 如何在mapbox颤振中添加符号
- javascript - 如何在 JavaScript 中为当前日期和格式添加天数?
- laravel - InvalidArgumentException:Laravel CronJob 中的 C:\xampp\htdocs\myapp\vendor\ 中缺少数据
- javascript - 使用 JavaScript 和 CSS 定位子菜单
- javascript - 此代码如何将字符串添加到数组列表并返回它?
- file - 如何将 imagePath 更改为文件?
- xamarin - Xamarin Android 在 Azure Pipeline 中构建失败