Fabricjs line coordinates after movement

孤街醉人 提交于 2020-12-12 11:08:04

问题


Fiddle - jsfiddle

sequencing:

  1. draw the line at coordinates (x1 = 50, y1 = 50, x2 = 450, y2 = 50)
  2. Checking coordinate y1. y1 = 50
  3. Move the line on the y-axis by 50 pixels.
  4. Checking coordinate y1. LEFT y1 = 50 ??? Why is that? And how to get the true coordinates?

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

        var line = new fabric.Line([50, 50, 450, 50], {            
            stroke: 'blue',
            strokeWidth : 10,
            hasControls: false,
            hasBorders: false,
            lockMovementX: true,
            lockMovementY: true,
            hoverCursor: 'default'

        });



canvas.add(line);


document.querySelector('#getLineY').onclick=function(e) {
    alert(line.get('y1'));
}

document.querySelector('#movedown').onclick=function(e) {
  line.top=line.top+50;
    canvas.renderAll();

}
canvas {
    border: solid 1px black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.1.0/fabric.all.min.js"></script>
<button id="getLineY">getLineY</button>
<button id="movedown">movedown</button>

        <canvas id="c" width="500" height="500" ></canvas>

回答1:


I've written a function for that:

function calcLineCoords(line) {
  const {
    tl, tr, bl, br,
  } = line.calcCoords();
  let coordsStart;
  let coordsEnd;

  if (line.x1 > line.x2) {
    if (line.y1 > line.y2) {
      coordsStart = br;
      coordsEnd = tl;
    } else {
      coordsStart = tr;
      coordsEnd = bl;
    }
  } else {
    // eslint-disable-next-line no-lonely-if
    if (line.y1 > line.y2) {
      coordsStart = bl;
      coordsEnd = tr;
    } else {
      coordsStart = tl;
      coordsEnd = br;
    }
  }

  return [coordsStart, coordsEnd];
}

// Usage:
// const [coordsStart, coordsEnd] = calcLineCoords(line);



回答2:


As you are changing line.top, with

line.top=line.top+50; 

Why not use that for your query, eg..

    alert(line.get('y1') + '..' + line.get('top'));

'y1' will be 50, 'top' will be 100.




回答3:


unfortunately, there are no ways from existing fabric line attributes. fabric is not updating their coordinates or width of the line object while moving. but they did update the top and left values.

What I did to solve my problem was, I have calculated the current width and height of the line from its bounding box using the method getBoundingRect(), The top and left values can be used to plot the first point(x1,y1) and then added left to width and top to height to obtain the second point(x2,y2).

let lineObj be your current fabric line object. then,

var boundingRect = lineObj.getBoundingRect();

lineObj.x1 = boundingRect.left;
lineObj.y1 = boundingRect.top;
lineObj.x2 = boundingRect.left + boundingRect.width;
lineObj.y2 = boundingRect.top + boundingRect.height;

hope this will help someone.




回答4:


x1, x2, y1, y2 are cached values and always refer to the initial start and end point. Therefore, you have to calculate the coords of the moved or scaled line object for yourself.

I have not figured out until today how to calculate rotation, since this involves some advanced maths with trigonometry and multiple if/else scenarios based on the quadrants and flips.

Moreover, @Andrey's answer is only partially correct. The function is wrong as soon as you flip the line in whichever direction (x or y).

A better approach would be to use top and left values (which luckily are not cached and updated during a movement), then ask for the start and end coords using line.calcLinePoints() relative to the top & left values.

Solving scaling is done by using the scaleX and scaleY values.

Here is an example

/**
 * Works with moving, scaling and flipping BUT NOT rotation
 */
function calcLineCoords(line){
  const linePoints = line.calcLinePoints();
  const scaleX = line.scaleX || 1;
  const scaleY = line.scaleY || 1;

  let startCoords, endCoords;
  if ((line.flipY && line.flipX) || (!line.flipY && !line.flipX)) {
    startCoords = {
      x: line.left + linePoints.x1 * scaleX,
      y: line.top + linePoints.y1 * scaleY,
    };
    endCoords = {
      x: line.left + linePoints.x2 * scaleX,
      y: line.top + linePoints.y2 * scaleY,
    };
  } else {
    startCoords = {
      x: line.left + linePoints.x1 * scaleX,
      y: line.top + linePoints.y2 * scaleY,
    };
    endCoords = {
      x: line.left + linePoints.x2 * scaleX,
      y: line.top + linePoints.y1 * scaleY,
    };
  }
}


来源:https://stackoverflow.com/questions/31706847/fabricjs-line-coordinates-after-movement

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!