Как я могу получить исходные координаты из элементов activeObjects [] множественного выбора? - PullRequest
0 голосов
/ 17 января 2019

Я кодирую веб-страницу, используя Fabricjs.Прежде всего, я рисую несколько кругов на холсте, а затем разрешаю пользователю выбрать один или несколько из них.Я написал выделение: создал обработчик, который создает форму и печатает координаты каждого выбранного объекта в этой форме.Проблема в том, что эти координаты полностью отличаются от тех, которые я установил, когда создавал круги.Однако это происходит только тогда, когда пользователь выбирает два или более круга.

Что я в основном делаю: я вызываю метод getActiveObjects (), который возвращает массив activeObjects [], затем я делаю цикл для доступа к левому и верхнемусвойства каждого элемента этого массива.Я также попытался сделать те же манипуляции с этими числами, как предлагает этот ответ: Как установить относительную позицию (oCoords) в 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, «чёрный») и я выберу их, я прочитаю в форме значения 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 голосов
/ 17 января 2019

Вы должны принять во внимание преобразование объекта, который применяется группой. Когда вы просто делаете выделение, вы можете подумать, что нет преобразования, но 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>

Мне кажется довольно солидным, когда я обновил свой ответ вашим кодом.

...