Javascript toSVG方法不适用于具有Fabric.js的扩展类
我正在用Fabric.js做一个项目 现在我需要创建一个自定义类并将其导出到SVG 我正在使用Fabric.js教程开始: 以下是javascript代码:Javascript toSVG方法不适用于具有Fabric.js的扩展类,javascript,svg,fabricjs,Javascript,Svg,Fabricjs,我正在用Fabric.js做一个项目 现在我需要创建一个自定义类并将其导出到SVG 我正在使用Fabric.js教程开始: 以下是javascript代码: var LabeledRect = fabric.util.createClass(fabric.Rect, { type: 'labeledRect', initialize: function(options) { options || (options = { }); this.callSuper('init
var LabeledRect = fabric.util.createClass(fabric.Rect, {
type: 'labeledRect',
initialize: function(options) {
options || (options = { });
this.callSuper('initialize', options);
this.set('label', options.label || '');
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.get('label')
});
},
_render: function(ctx) {
this.callSuper('_render', ctx);
ctx.font = '20px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width/2, -this.height/2 + 20);
}
});
var canvas = new fabric.Canvas('container');
var labeledRect = new LabeledRect({
width: 100,
height: 50,
left: 100,
top: 100,
label: 'test',
fill: '#faa'
});
canvas.add(labeledRect);
document.getElementById('export-btn').onclick = function() {
canvas.deactivateAll().renderAll();
window.open('data:image/svg+xml;utf8,' + encodeURIComponent(canvas.toSVG()));
};
以下是HTML:
<canvas id="container" width="780" height="500"></canvas>
<a href="#" id="export-btn">Export SVG</a>
这是我的名片
我做错了什么
提前感谢。问题是没有SVG等价于
fillText
,所以FabricJS似乎忽略了它。
是使用fabric.Group
并构建内部Rect
和Text
var LabeledRect = function(options) {
var rect = new fabric.Rect({
width: options.width,
height: options.height,
fill: options.fill
});
var label = new fabric.Text(options.label);
var group = new fabric.Group([rect, label]);
group.left = options.left;
group.top = options.top;
group.toSVG = function() {
var e=[];
for(var t = 0; t < this._objects.length; t++)
e.push(this._objects[t].toSVG());
return'<g transform="'+this.getSvgTransform()+'">'+e.join("")+"</g>"
};
return group;
};
var LabeledRect=函数(选项){
var rect=new fabric.rect({
宽度:options.width,
高度:options.height,
填充:options.fill
});
var label=new fabric.Text(options.label);
var group=newfabric.group([rect,label]);
group.left=options.left;
group.top=options.top;
group.toSVG=函数(){
var e=[];
对于(var t=0;t
我重写toSVG
的原因是默认实现以相反的顺序遍历子项(for(var t=this._objects.length;t-->)
)。我不知道它为什么会这样做,但文本呈现在矩形下面。结构中的每个“类”(矩形、圆形、图像、路径等)都知道如何输出其SVG标记。负责它的方法是toSVG
。例如,您可以看到或
因为您在这里创建了fabric.Rect
的子类,并且没有指定toSVG
,所以使用了prototype链中下一个对象的toSVG
。继承链中的下一个“类”恰好是fabric.Rect
,因此您将看到fabric.Rect.prototype.toSVG
的结果
解决方案很简单:在子类中指定toSVG
。从理论上讲,您需要将fabric.Rect#toSVG
和fabric.Text#toSVG
中的代码组合起来,但为了避免重复并保持可维护性,我们可以利用一些技巧:
toSVG: function() {
var label = new fabric.Text(this.label, {
originX: 'left',
originY: 'top',
left: this.left - this.width / 2,
top: this.top - this.height / 2,
fontSize: 20,
fill: '#333',
fontFamily: 'Helvetica'
});
return this.callSuper('toSVG') + label.toSVG();
}
当然,“fontSize”、“fill”和“fontFamily”在理想情况下应该移动到实例级属性,以避免在那里重复它们
这是一个改进的测试-
@Sergiu Paraschiv向团队提出的建议是另一个同样可行的解决方案。谢谢@kangax!:)这对我帮助很大!