【问题标题】:Fabric.js auto-size group controls when contained objects change size当包含的对象改变大小时,Fabric.js 自动调整组大小
【发布时间】:2014-11-06 00:47:15
【问题描述】:

当我有一组织物 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(),因此它们的边界绘制正确。

【问题讨论】:

    标签: angularjs fabricjs


    【解决方案1】:

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

    错误 #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: 组的选择区域在其包含的 IText 对象更改大小后不会刷新,即使您调用 setCoords。如果您使用 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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-03
      • 1970-01-01
      • 2015-06-06
      • 2015-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      相关资源
      最近更新 更多