shaver
shaver

Reputation: 157

group members not centering in group

I'm creating a simple group, with circle and text, and I expected the text to be centered over the circle. (Like in the group demo on the front page of fabricjs.com!)

var text = new fabric.Text('hello world', {
    fontSize: 30
});
    
var circle = new fabric.Circle({
    radius: 100,
    fill: '#eef',
});
    
var group = new fabric.Group([ circle, text ], {
    left: 150,
    top: 100,
    angle: -10
});
    
canvas.add(group);

I've in fact taken that from the beginning of the tutorial page on Groups, but removed the circle's scaleY to make the non-centering more obvious.

I have a JSFiddle of it up, and tracing thorough the Fabric code I don't see anything that would actually center the contents; Group.prototype._updateObjectCoords just offsets by the group's position, making the contents' top and left simply be relative to the top-left of the group itself. And yet, it seems to work on the demo page!

http://jsfiddle.net/xGtvj/

Upvotes: 2

Views: 2258

Answers (2)

LatentDenis
LatentDenis

Reputation: 2991

If you were looking to center an object within a group but also keep scaling the same throughout all sizes in regards to the object width/height, here's how:

let bounds = group.getBoundingRect();

const scaleFactor = Math.min(
    Math.min(1, bounds.width / fabricObject.width),
    Math.min(1, bounds.height / fabricObject.height)
);

fabricObject.scale(scaleFactor);

fabricObject.set({
    top: bounds.top + Math.max(bounds.height - fabricObject.height * scaleFactor, 0)/2,
    left: bounds.left + Math.max(bounds.width - fabricObject.width * scaleFactor, 0)/2,
});

group.addWithUpdate(fabricObject);
this.canvas.renderAll();

This approach is done through a "parent" rectangle inside of a group. My initialization approach would be:

var rect = new fabric.Rect({
    left: 100,
    top: 50,
    width: 450,
    height: 200,
    fill: '#e3e3e3',
});

var group = new fabric.Group([rect], {
    name: 'Rectangle',
});

this.canvas.add(rectGroup);

StackBlitz: https://stackblitz.com/edit/angular-pg4fis

Upvotes: 0

physiocoder
physiocoder

Reputation: 712

Starting from 1.4.0 fabric.js changed default object origin to 'left'and 'top'. Instead you need object property originX and originY to be center:

fabricObject.set({
    originX: "center",
    originY: "center"
});

Here is your fiddle modified: http://jsfiddle.net/KSGL8/

You can also globally revert to previous 1.4.0 behavior with these two lines:

// From 1.4.0 on, Fabric.js put left/top as default, restore old center/center
fabric.Object.prototype.originX = "center";
fabric.Object.prototype.originY = "center";

Upvotes: 5

Related Questions