由于transform:translate rule,无法看到画布上的SVG(使用fabricjs)

时间:2016-01-08 17:52:51

标签: html5 canvas svg fabricjs

SVG出现问题我正在使用fabric.js加载到画布中 在屏幕截图中,您将看到边界框和图标不重叠:

问题似乎来自SVG中的以下属性值:transform="translate(-255.7-577)"

我遇到麻烦(使用fabric.js)搞清楚如何调整SVG以便不会发生这种翻译。

任何指导,无论是fabric.js特定的还是仅仅是本机画布方法都将受到赞赏。似乎无法弄清楚如何调整SVG对象中的路径。

1 个答案:

答案 0 :(得分:2)

Fabricjs目前还没有对transformMatrix的适当支持。 每个svg解析转换属性从元素到父节点都会被解析并合并到一个矩阵中,然后存储在object.transformMatrix中。

如果导入对其进行分组的对象,则正确处理此transforMatrix

fabric.loadSVGFromURL('mysvg.svg', function(objects, options) { 
    var myobj = fabric.util.groupSVGElements(objects, options);
    canvas.add(myobj ); 
}); 

这足以正确显示它。

如果出于任何原因,您希望它们不在pathgroup对象中,则必须执行以下步骤: 1)从url加载svg 2)逐个对象用当前状态对象解析变换矩阵属性 3)将对象添加到画布。

这可以通过以下代码完成:

fabric.Object.prototype._removeTransformMatrix = function(addTranslate) {

  var left = this.left;
  var top = this.top;

  if (this.type !== 'text' && this.type !== 'i-text') {
    left += this.width / 2;
    top += this.height / 2;
  }

  var matrix = fabric.util.multiplyTransformMatrices(this.transformMatrix ||  [1, 0, 0, 1, 0, 0], [1, 0, 0, 1, left, top]);
  var options = fabric.util.qrDecompose(matrix);
  this.scaleX = options.scaleX;
  this.scaleY = options.scaleY;
  this.angle = options.angle;
  this.skewX = options.skewX;
  this.skewY = 0;
  this.flipX = false;
  this.flipY = false;
  var point = new fabric.Point(options.translateX, options.translateY);
  this.setPositionByOrigin(point , 'center', 'center');
  this.transformMatrix = null;
};

然后打电话:

fabric.loadSVGFromURL('mysvg.svg', function(objects, options) { 
    for (var i = 0; i < objects.length; i++) {
      objects[i]._removeTransformMatrix();
      canvas.add(objects[i]); 
    }
});

应该为你做的伎俩。

这将允许您解析任何复杂的转换,而不仅仅是翻译转换。 此代码假定来自svg的对象可能具有与0不同的x和y,但不会在transform属性之外携带任何角度或倾斜。 SVG对象也是左上角的。此代码不会删除fabricJS环境中任何自定义对象的任何自定义transformMatrix。

当然使用最新的fabricjs。不使用1.5.0

这里提到了这个代码。 http://jsfiddle.net/asturur/7gvJG/66/

其中一个svg的translate属性表示如下:

translate(-x-y);

检查w3cspesc: http://www.w3.org/TR/SVG/coords.html#TransformAttribute 看起来这个空间是强制性的:

translate:
    "translate" wsp* "(" wsp* number ( comma-wsp number )? wsp* ")"
comma-wsp:
    (wsp+ comma? wsp*) | (comma wsp*)

它说

"translate"+ 0 or more spaces + "("  + number + optionally a comma-wsp + another number + ")"

和逗号-wsp定义为:

1 or more spaces, 0 or 1 comma, any number of spaces. OR a comma + any number of spaces.

所以至少应该有一个空格或逗号。

2016年1月15日由@onassar 更新 虽然上面的逻辑有所帮助,但我意识到一种更简单的方法是格式化返回的SVG xml:

xml.replace(/translate\((\-?[0-9\.]+)(\-?[0-9\.]+)\)/gi, 'translate($1 $2)')

这样做了,但如果您正在寻找其他解决方案,上述步骤也会有所帮助。