使用FabricJS创建标记(Rect + Text)

时间:2016-03-16 16:38:59

标签: canvas fabricjs

我正在调用一个标记,一个带有可编辑文本的彩色矩形。 我不希望Text变形,它必须保持字母宽度并且如果太小则包裹线条。文本应该以矩形为中心。

要做到这一点,我需要创建Fabric对象的子类,看起来我有2个解决方案:

  1. 使用tutorials中的LabeledRect,这是一个带有Text in属性的Rect。

  2. 使用带有Rect和Textbox的组。但是这是一个组,当Textbox在组中时,我找不到编辑文本的任何工作解决方案。 See fiddle

    fabric.Tag = fabric.util.createClass(fabric.Group, {
    type: 'ce.tag',
    
    initialize: function() {
    
        options = {};
    
        options.top     = 10;
        options.left    = 10;
    
        var defaults    = {
            width:  300,
            height: 30,
            originX: 'center',
            originY: 'center'
        };
    
        var items   = [];
    
        items[0]    = new fabric.Rect($.extend({}, defaults, {
            fill: '#77AAFF',
        }));
    
        items[1]    = new fabric.Textbox('Nouvelle étiquette', $.extend({}, defaults, {
            textAlign: 'center',
            fontSize: 20
        }));
    
        this.callSuper('initialize', items, options);
    
    },
    });
    
    canvas.add(new fabric.Tag())
    
  3. 选项#2(可能是#1)的问题是文本应该是可编辑的,而不是。

    我目前在选项#2中有一些渲染问题,在反序列化时,fill属性被重置为默认值(黑色)。 See fiddle 实际上,这是Group的默认值,FabricJS将委托属性应用于对象。 Juste将“delegatedProperties:{}”设置为Tag声明,并且不委托任何属性。

    注意:使用群组并不是一个好主意,群组及其子群之间有很多属性可以委派或分享。

1 个答案:

答案 0 :(得分:2)

我正在努力解决同样的问题。从我对它的研究到目前为止,我看到两个选择可以构建到你的两条路径中:

1)按照建议通过LabeledRect创建扩展类。但是,不是扩展Rectangle类 - 而是使用矩形绘图函数扩展IText(或Textbox)类。绘制矩形的ctx逻辑不应该太难以移植到IText类中,这样我们就可以获得IText为editablity提供的所有好方法。

您可以在版本1.6.0-rc.1

中的第14,553行中看到_render矩形代码

2)正如您所注意到的,当您对事物进行分组时,您会失去可编辑性。 A previous question发布了一个工作小提琴,显示在选择项目时取消组合/重新组合的代码。这允许用户访问IText功能,然后在完成编辑重新组时将它们全部重新组合在一起。

我发现的所有其他问题都回到了这个答案。

这种方法的问题:首先,原始海报的代码可以工作,但仅限于他的特定用例 - 它需要进行推广(理想情况下可以设置为服务)。其次,我测试了在该示例中向画布添加其他对象,并且在重新分组期间,所有对象都被添加到组中(包括不在原始组中的对象)。

如果你决定走这条路,我认为你需要: a)将其变为服务,因此可以在画布中的任何对象上调用它 b)想出一些方法将重新分组限制为只有你想要的对象。

您应该能够通过使用交叉点仅对IText正在触摸的对象进行分组(请参阅Intersections example here)或对对象使用一些自定义标记元素以了解它们应属于哪个组来执行b) (例如,为fabric.rect的自定义子类创建自定义" group-id"属性,就像在LabeledRect教程中创建自定义子类一样)。

如果我能够实施其中任何一项,我会跟进(但我刚刚开始使用Fabric / Javascript,所以我可能无法做到)。