如何从多项选择的activeObjects []元素中获取原始坐标? [英] How can I obtain the original coordinates from the activeObjects[] elements of a multiple selection?

查看:71
本文介绍了如何从多项选择的activeObjects []元素中获取原始坐标?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am coding a web page using Fabricjs. First of all, I draw some circles in my canvas, then I allow the user to select one or more of them. I wrote a selection:created handler that creates a form and prints the coordinates of each selected object in that form. The problem is that those coordinates are completely different from the ones I set when I created the circles. However, this happens only when the user select two or more circle.

我基本上要做的是:调用返回ActiveObjects []数组的getActiveObjects()方法,然后循环访问该数组的每个元素的left和top属性.我也尝试对这些数字进行相同的处理,如此答案所建议的:

What I basically do is: I call the getActiveObjects() method that returns an activeObjects[] array, then I loop to access the left and top properties of each element of that array. I have also tried to make same manipulation of those numbers as this answer suggests: How to set relative position (oCoords) in FabricJs?

这是我创建圈子的方式:

This is how I create circles:

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);
}

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

And this is the selection:created handler:

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个圆圈),那么我将以其他形式读取完全不同的值.

I expect that if I create two circles calling drawCircle(10,20,2,'black') and drawCircle(30,30,2,'black') and I select them, I will read in the form the values 10, 20, 2, 30, 30 and 2; instead, only the radius values are correct, but the coordinates are respectively (-10, 395) and (10, 405). As you can see, the distance between the two circle is still the same, but their coordinates are completely different from the original. Moreover, if I modify the selection (let's say I select 3 circles), in the form I will read other completely different values.

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>

推荐答案

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

you have to take in consideration the transform of the object that is applied by the group. When you just make the selection you may think there are no transformation, but fabricjs is drawing those circles around the center of the selection, there is a translate operation.

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

A way to solve it generally for any transform ( scale, rotate, ) is:

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>

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

Loos pretty solid to me now that i updated my answer with your code.

这篇关于如何从多项选择的activeObjects []元素中获取原始坐标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆