如何从多项选择的activeObjects []元素中获取原始坐标?

时间:2019-01-17 09:14:35

标签: javascript html fabricjs

我正在使用Fabricjs编码网页。首先,我在画布上绘制了一些圆圈,然后允许用户选择一个或多个圆圈。我写了一个selection:created处理程序,该处理程序创建一个表单并打印该表单中每个选定对象的坐标。 问题在于这些坐标与我创建圆时设置的坐标完全不同。但是,只有当用户选择两个或多个圆圈时,这种情况才会发生。

我基本上要做的是:调用返回ActiveObjects []数组的getActiveObjects()方法,然后循环访问该数组每个元素的left和top属性。我也尝试对这些数字进行相同的处理,如答案所示:How to set relative position (oCoords) in FabricJs?

这是我创建圈子的方式:

function drawCircle( x, y, r, color ){
    var circle = new fabric.Circle({radius: r, fill: color, originX: 'center', originY: 'center', left: x, top: y, lockMovementX: true, lockMovementY: true, hasControls: false});
    canvas.add(circle);
}

这是选择:创建的处理程序:

canvas.on('selection:created', function(e){
    var activeObjects = canvas.getActiveObjects();
    var length = activeObjects.length;
    var myForm = document.createElement("form");

    for( var i=0; i<length; i++){                   
        var x = document.createElement("input");
        x.setAttribute('type',"text");
        x.setAttribute('name', "x"+i);
        x.setAttribute('value', activeObjects[i].left);

        var y = document.createElement("input");
        y.setAttribute('type',"text");
        y.setAttribute('name', "y"+i);
        y.setAttribute('value', activeObjects[i].top );

        var radius = document.createElement("input");
        radius.setAttribute('type',"text");
        radius.setAttribute('name', "radius"+i);
        radius.setAttribute('value', activeObjects[i].radius );

        f.appendChild(radius);
        f.appendChild(x);
        f.appendChild(y);                   
    }
})

我希望如果我创建两个调用drawCircle(10,20,2,'black')和drawCircle(30,30,2,'black')的圆并选择它们,我将以值的形式读取10、20、2、30、30和2;相反,只有半径值正确,而坐标分别是(-10,395)和(10,405)。如您所见,两个圆之间的距离仍然相同,但是它们的坐标与原始坐标完全不同。 而且,如果我修改选择(假设我选择了3个圆圈),那么我将以其他形式读取完全不同的值。

var canvas = new fabric.Canvas('myCanvas');

fabric.Group.prototype.lockMovementX = true;
fabric.Group.prototype.lockMovementY = true;
fabric.Group.prototype.hasControls = false;

var circle = new fabric.Circle({radius: 2, fill: 'black', originX: 'center', originY: 'center', left: 10, top: 400-20, lockMovementX: true, lockMovementY: true, hasControls: false});
canvas.add(circle);

var circle = new fabric.Circle({radius: 2, fill: 'black', originX: 'center', originY: 'center', left: 30, top: 400-30, lockMovementX: true, lockMovementY: true, hasControls: false});
canvas.add(circle);

canvas.on('selection:created', function(e){
  var activeObjects = canvas.getActiveObjects();
  var length = activeObjects.length;
  
  var activeSelection = canvas.getActiveObject();
  var matrix = activeSelection.calcTransformMatrix();
  
  var form = document.createElement("form");
  
  for( var i=0; i<length; i++){
    var obj = activeObjects[i];
    var objectPosition = { x: obj.left, y: obj.top };
    var finalPosition = fabric.util.transformPoint(objectPosition, matrix);          									    

						var radius = document.createElement("input");
						radius.setAttribute('type',"text");
						radius.setAttribute('name', "raggio"+i);
						radius.setAttribute('value', obj.radius );
						
						var x = document.createElement("input");
						x.setAttribute('type',"text");
						x.setAttribute('name', "x"+i);
						x.setAttribute('value', finalPosition.x );

						var y = document.createElement("input");
						y.setAttribute('type',"text");
						y.setAttribute('name', "y"+i);
						y.setAttribute('value', 400-finalPosition.y );

						form.appendChild(radius);
						form.appendChild(x);
						form.appendChild(y);
					}					

					document.getElementsByTagName('body')[0].appendChild(form);					
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>


<h1> Grid </h1>

<canvas id="myCanvas" width="600" height="400" style="border: 1px solid #000000;"></canvas>

1 个答案:

答案 0 :(得分:1)

您必须考虑由组应用的对象的变换。 当您仅进行选择时,您可能会认为没有变换,但是fabricjs在选择的中心周围绘制了这些圆圈,这是一个平移操作。

通常针对任何变换(缩放,旋转,)解决它的一种方法是:

var canvas = new fabric.Canvas('myCanvas');

fabric.Group.prototype.lockMovementX = true;
fabric.Group.prototype.lockMovementY = true;
fabric.Group.prototype.hasControls = false;

var circle = new fabric.Circle({radius: 2, fill: 'black', originX: 'center', originY: 'center', left: 10, top: 20, lockMovementX: true, lockMovementY: true, hasControls: false});
canvas.add(circle);

var circle = new fabric.Circle({radius: 2, fill: 'black', originX: 'center', originY: 'center', left: 30, top: 30, lockMovementX: true, lockMovementY: true, hasControls: false});
canvas.add(circle);

canvas.on('selection:created', function(e){
  var activeObjects = canvas.getActiveObjects();
  var length = activeObjects.length;
  
  var activeSelection = canvas.getActiveObject();
  var matrix = activeSelection.calcTransformMatrix();
  
  var form = document.createElement("form");
  
  for( var i=0; i<length; i++){
    var obj = activeObjects[i];
    var objectPosition = { x: obj.left, y: obj.top };
    var finalPosition = fabric.util.transformPoint(objectPosition, matrix);          									    

						var radius = document.createElement("input");
						radius.setAttribute('type',"text");
						radius.setAttribute('name', "raggio"+i);
						radius.setAttribute('value', obj.radius );
						
						var x = document.createElement("input");
						x.setAttribute('type',"text");
						x.setAttribute('name', "x"+i);
						x.setAttribute('value', finalPosition.x );

						var y = document.createElement("input");
						y.setAttribute('type',"text");
						y.setAttribute('name', "y"+i);
						y.setAttribute('value', finalPosition.y );

						form.appendChild(radius);
						form.appendChild(x);
						form.appendChild(y);
					}					

					document.getElementsByTagName('body')[0].appendChild(form);					
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>


<h1> Grid </h1>

<canvas id="myCanvas" width="100" height="100" style="border: 1px solid #000000;"></canvas>

现在,我用您的代码更新了答案,对我来说确实很坚实。