3

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>
Ashish Kakkad
  • 23,586
  • 12
  • 103
  • 136
SanOld
  • 41
  • 1
  • 3
  • You need to post your code here, not only provide a link to fiddle. [Check this page for how to ask good questions]( http://stackoverflow.com/help/how-to-ask) – Racil Hilan Jul 29 '15 at 17:13

4 Answers4

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);
  • Andrey, can you take a look at [this](https://stackoverflow.com/questions/60416193/fabric-js-calculating-line-coordinates-when-the-line-moves-in-a-group)? – ps0604 Feb 27 '20 at 01:13
  • This answer is only partially true! Se my solution below for a more completed one. – Advena Nov 05 '20 at 11:51
1

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,
    };
  }
}
Advena
  • 1,664
  • 2
  • 24
  • 45
0

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.

Ian
  • 13,724
  • 4
  • 52
  • 75
  • 1
    The problem arose with the definition of the coordinate line after line move and zoom user via drag and drop. After dragging the left, top change, but the location in which the line was based remain unchanged. At the moment, I, I think, take care of the problem. The coordinates x, y is only used in the construction of the line. Further work with the line as a rectangle with the object. To calculate the true origin line will transform the coordinates x, and which built the line in a new coordinate system based on the values ​​of scale and rotate. – SanOld Jul 31 '15 at 07:50
0

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.

iamntg
  • 29
  • 6
  • I know that this is an old answer, but this is not correct when I draw a line from bottom-right corner to top-left corner. In that case, your assumption will not be correct. – Fran Verona Aug 25 '17 at 10:17
  • this is not working, because it return size even with controls and it is not right... – Raiper34 May 03 '18 at 21:29