В угловом приложении я реализовал простую доску с Fabric.js, которая позволяет пользователю рисовать некоторые основные фигуры и рисовать от руки.Фигуры пустые и заполнены кругом и прямоугольником, а также базовым шаблоном диаграммы UML, представляющим собой два отдельных ряда друг над другом.
Когда я выбираю один или несколько объектов, положение всех экземпляровЛинии и круги автоматически преобразуются в начало координат холста, оставляя маркер выделения только в исходном положении.Как ни странно, этого не происходит с шаблоном UML, который, в конце концов, также состоит из двух простых каналов, таких как трансформатор, за исключением другого начального размера.Рисунки от руки из встроенной функции тоже не касаются.
Когда эти элементы выбираются индивидуально, они остаются «в положении».Я не переписывал никакие методы выбора.
Стоит упомянуть, что доска расположена в виджете внутри приложения, что означает, что вы можете перетаскивать доску по экрану, отсюда и значения adjustedX
и adjustedY
.Однако объекты всегда преобразуются в начало координат, и другие объекты работают нормально, поэтому я склоняюсь к тому, чтобы исключить это.
одиночный выбор
выбор группы: все выбранные объекты
выбор группы: только прямоугольникselected
Это код, который создает мой холст и две фигуры
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
активируется при переходе в «режим выбора» в приложении.