通过选择画布上的多个现有对象来创建组时移动光标重影

时间:2018-09-20 14:53:46

标签: fabricjs move

fabricjs_2.3.6

我正在使用一个编辑器,该编辑器将允许用户动态创建文本框图像和矩形,并且该项目的这一部分效果很好。画布上的所有对象在创建组之前都会预先存在,因此我不想对任何结构进行硬编码。我还想保留分组项目之间的位置关系。

在通过在画布上选择2个或更多现有对象来创建组来创建组时遇到问题。我的代码有一个例外,如果在创建组时所选项目不在画布的左上角,则分组的对象将根据需要保留在原始位置,但移动手柄位于画布的左上角。如果单击“移动光标”手柄重影,然后单击画布上的空白区域,问题就会消失,然后一切正常。

我可能没有运气来寻找解决方案,可能是因为我不确定是什么因素控制了移动光标在画布上的位置,或者实际上是否将其称为“移动光标”。

这是单击组按钮后来自我的jsfiddle的图片: enter image description here 这是一个演示问题的jsfiddle链接:https://jsfiddle.net/Larry_Robertson/xfrd278a/

这是我的代码:

HTML

<span> Test 1: select both the line and the text objects with the mouse then click group, works great.</span>
<br/>
<span> Test 2: select both the line and the text objects with the mouse, move the selction to the center of the canvas then click group. This creates the problem where a ghost move handle is left behind in the upper left corner of the canvas.  The move handle did not update to the correct position when the group was created.  If you hover the mouse in the upper left of canvas you will see the move cursor. Click on the move cursor then click any blank part of the canvas then you can reselect the group and it moves properly.  What am I doing wrong???</span>
<br/>
<button id="group">group</button>
<canvas id="c" height="300" width="500"></canvas>

JS

var canvas = new fabric.Canvas('c');
var text = new fabric.Text('hello world', {
  fontSize: 30,
  originX: 'left',
  originY: 'top',
  left: 0,
  top: 0
});
var line = new fabric.Line([10, 10, 100, 100], {
  stroke: 'green',
  strokeWidth: 2
});
canvas.add(line);
canvas.add(text);
canvas.renderAll();

$('#group').on(("click"), function(el) {
  var activeObject = canvas.getActiveObject();
  var selectionTop = activeObject.get('top');
  var selectionLeft = activeObject.get('left');
  var selectionHeight = activeObject.get('height');
  var selectionWidth = activeObject.get('width');
  if (activeObject.type === 'activeSelection') {
    var group = new fabric.Group([activeObject], {
      left: 0,
      top: 0,
      originX: 'center',
      originY: 'center'
    });
    canvas.add(group);
    deleteSelectedObjectsFromCanvas();
    canvas.setActiveObject(group);
    group = canvas.getActiveObject();
    group.set('top', selectionTop + (selectionHeight / 2));
    group.set('left', selectionLeft + (selectionWidth / 2));
    group.set('originX', 'center');
    group.set('originY', 'center');
    canvas.renderAll();
  }
});


function deleteSelectedObjectsFromCanvas() {
  var selection = canvas.getActiveObject();
  var editModeDected = false;
  if (selection.type === 'activeSelection') {
    selection.forEachObject(function(element) {
      console.log(element);
      if (element.type == 'textbox') {
        if (element.isEditing == true) {
          //alert('At least one textbox is currently being edited.  No objects were deleted');
          editModeDected = true;
        }
      }
    });
    if (editModeDected == true) {
      return false;
    }
    // Its okay to delete all selected objects
    selection.forEachObject(function(element) {
      console.log('removing: ' + element.type);
      //element.set('originX',null);
      //element.set('originY',null);
      canvas.remove(element);
      canvas.discardActiveObject();
      canvas.requestRenderAll();
    });
  } else {
    if (selection.isEditing == true && selection.type == 'textbox') {
      //alert('Textbox is currently being edited.  No objects were deleted');
    } else {
      canvas.remove(selection);
      canvas.discardActiveObject();
      canvas.requestRenderAll();
    }
  }
}

CSS

#c {
  margin: 10px;
  padding: 10px;
  border: 1px solid black;
}

1 个答案:

答案 0 :(得分:1)

对代码进行更改后,请始终对已更改的对象执行setCoords

这是您可以在renderAll之后添加的一个衬纸,以解决您的问题:

    ...
    group.set('originY', 'center');
    canvas.renderAll();
    canvas.forEachObject(function(o) {o.setCoords()});