当包含的对象改变大小时,Fabric.js 自动调整组大小
Posted
技术标签:
【中文标题】当包含的对象改变大小时,Fabric.js 自动调整组大小【英文标题】:Fabric.js auto-size group controls when contained objects change size 【发布时间】: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()
,因此它们的边界绘制正确。
【问题讨论】:
【参考方案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();
【讨论】:
以上是关于当包含的对象改变大小时,Fabric.js 自动调整组大小的主要内容,如果未能解决你的问题,请参考以下文章