Canvas coordinates in Fabric.js have offset

2019-01-22 23:31发布

问题:

I just started with fabric.js and I have a (probably beginner) error:

I am using fabric with jquery with the following code:

$(document).ready(function () {

canvas = new fabric.StaticCanvas('scroller');

canvas.add(
  new fabric.Rect({ top: 0, left: 0, width: 140, height: 100, fill: '#f55' })
);

});

This code should draw a 140x100 Rectangle on the canvas. Sadly, only a quarter of the Rectangle appears. If I change the top and left values to higher numbers, more of the Rectangle appears on the canvas.

So it seems, that the canvas origin is not at 0/0, but at sth. higher.

Does someone know how to fix this or what I am doing wrong?

Thanks in advance, McFarlane

回答1:

Here is a jsfiddle link with some examples http://jsfiddle.net/pukster/sdQ7U/2/

My guess is that fabric.js calculates everything from the origin (middle point) since it is drawing exactly one quarter of a rectangle even with a canvas 10 times the size of the rectangle. My guess is that top and left actually refer to the origin and not the top and left sides of the imaginary bounding box. Trouble is there is very little documentation on fabricjs. Is there any reason you are using fabricjs and not easeljs

EDIT Here's the same fiddle but with squares instead of rectangles (it is more clear) http://jsfiddle.net/pukster/sdQ7U/3/

EDIT OK I am now almost absolutely certain that fabric.js uses the center as the top/left. I ripped their example off of their site and overlayed it with the transparent couterpart to those shapes had they been coded in pure canvas http://jsfiddle.net/pukster/uathZ/2/ (blue border is the limit of the canvas element).

What you see is that the boxes are exactly offset by half but the circle (I only drew a semi circle otherwise it would not have been discernable) is perfectly overlapped. This is b/c in HTML Canvas, the circle coordinates (x,y) refer to the origin and not the top left. I did not bother with the triangle b/c my trigonometry is a bit rusty. I personally think it's misleading to use the terms top and left, when x and y would have been more representative and shorter.



回答2:

Yes, this is highly unexpected and even more undocumented.

Workaround:

Set

originX: "left"
originY: "top"

for each created object.

edit: or use kangax simpler solution in the comment below.



回答3:

I want to comment but lack the reputation to do so. So anyway, here is what happens when I do the following:

fabric.Object.prototype.originX = "left";
fabric.Object.prototype.originY = "top";

The shape gets rendered fine but when I select it for resizing or moving, it gets offset to a different location. The best approach seems to be to set the coordinates for every object separately using the set() method.