当包含的对象更改大小时,Fabric.js自动大小组控件

时间:2014-09-11 22:44:04

标签: angularjs fabricjs

当我有一组结构IText对象并且我将它们的所有字体大小一起更改时,分组的文本对象都会根据字体大小缩小或增长,但组控件和边框保持不变而不是改变大小。我的问题是,如何在更改组内的对象后让组控件自动调整大小?

查看Fabric的代码,我无法弄清楚如何在组中首先设置边界。我尝试在组上调用_setCoords()setCoords(),但是在画布上将组移动到0,0并保持高度和宽度相同。调用_setCoords(true)无效。

我还尝试了以下代码,其中我尝试用包含相同对象的新组替换旧组,这理论上会绘制新的边界,但它似乎是一个笨重的解决方案。此外,它不起作用:新的组边界和控件不会出现。

var selected = [];
var all = scope.canvas.getObjects();
for(var x in all) {
    if(all.active) {
        selected[selected.length] = x;
    }
}
scope.canvas._discardActiveGroup();
var objects = [];
for(var x in selected) {
    objects[x] = scope.canvas.getObjects()[x];
}
var group = new fabric.Group(objects,{
    originX: 'center',
    originY: 'center',
    canvas: scope.canvas
});

//Using $timeout so that this will wait until current $scope digest is finished
$timeout(function () {
    scope.canvas.setActiveGroup(group);
    scope.canvas.renderAll();
}, 0);
scope.canvas.renderAll();

修改

我认为这与另一个问题有关,即文本对象因字体大小更改而改变大小后,其选择区域仍保持在大小更改之前的位置。也就是说,如果在预调整大小的边界矩形内单击,它将选择对象,而不管调整大小后的边界矩形。只有在选择了其他对象或取消选择所有对象后,才能按预期对象进行选择。我为对象调用setCoords(),因此正确绘制了它们的边界。

1 个答案:

答案 0 :(得分:2)

这个问题分为两部分,正如我在编辑问题中所说的那样。解决我的问题需要以下两种解决方案。

错误#1:即使您使用setCoords(),IText对象的选择区域也会保持原样。这是因为setCoords()"根据当前角度,宽度和高度来设置角位置坐标" - 但它不会根据文本的更改来更新宽度和高度。这只发生在方法_renderViaNative(ctx)

期间
//inside _renderViaNative:
this.width = this._getTextWidth(ctx, textLines);
this.height = this._getTextHeight(ctx, textLines);

解决方案:因为我实际上正在使用IText的自定义降序类,所以我使用了setCoords函数的覆盖来修复它。像这样覆盖的东西应该是IText类的一部分:

/** @Override */
setCoords : function () {
    var ctx = this.canvas.getContext();
    var textLines = this.text.split(this._reNewline);
    this._setTextStyles(ctx);
    this.width = this._getTextWidth(ctx, textLines);
    this.height = this._getTextHeight(ctx, textLines);
    this.callSuper('setCoords');
},

错误#2:即使您拨打setCoords,群组的选择区域也不会在其包含更改大小的IText对象后刷新。如果您使用false参数调用_calcBounds,则会通过计算对象来设置组的中心点。中心点 - 但由于对象已被重置为相对于组中心的坐标为(0,0),因此重新计算以(0,0)为中心,因此整个组移动它的中心位于画布上的(0,0)处。如果您使用true参数调用_calcBounds,则会调整其原始中心周围的大小,而不是围绕新中心调整大小,并且您无法手动重置中心,因为这样也会使对象移动。

解决方案:重置对象'重新计算边界。坐标。我这样做主要是通过蚕食函数addWithUpdate(object)

// set the objects to their not-in-group coordinates
activeGroup.destroy(); 
// since _restoreObjectsState (inside destroy) set objects inactive, set them active
activeGroup.forEachObject(activeGroup._setObjectActive, activeGroup);
// now we can call _calcBounds without bouncing the group to 0,0
activeGroup._calcBounds();
// set the objects to their in-group coordinates
activeGroup._updateObjectsCoords();