无法将SVG正确导入画布

时间:2018-01-19 14:04:31

标签: javascript canvas svg fabricjs

我在将SVG导入画布并使用带有FabricJS的setZoom()时遇到问题。我正在使用版本" 2.0.0.rc4"。

我一直在尝试使用两种方法导入它们,但每种方法都有不同的问题:

1- loadSVGFromURL

fabric.loadSVGFromURL(src, function(objects, options) {
    let loadedObjects = new fabric.Group(group);
    var obj = fabric.util.groupSVGElements(objects, options);
    canvas.add(obj).renderAll();
});

使用此方法,某些SVG在画布上加载不正确,但缩放效果非常好。

loadSVGFromURL loads the SVG incorrectly

2-新fabric.Image

const image = new Image();
image.crossOrigin = "Anonymous";
image.src = src;

let imageObject;

image.onload = () => {
    imageObject = new fabric.Image(image, {
        scaleY: 1,
        scaleX: 1,
        cropX: 0,
        cropY: 0,
        lockUniScaling: true,
        crossOrigin: 'Anonymous'
    });
}

使用此方法可以正确导入每个SVG,但是当我尝试在我的应用程序中使用缩放时,视图框(容器)内的SVG形状会独立调整它们的大小,就像它被屏蔽,裁剪一样或剪裁。我猜是与preserveAspectRatio属性相关的东西,但我不能使它工作。

这是我用来设置缩放的方法。该方法适用于画布和其他对象,但使用前面描述的方法导入的SVG除外。

setCanvasZoom(value) {
    // value is from 10 to 500.
    // the zoomFactor will result in an integer from 0.1 to 5

    let zoomFactor = parseInt(value, 10) / 100;

    this.canvas.setZoom(zoomFactor);

    this.canvas.setWidth(this.templateDimensions.width * zoomFactor);
    this.canvas.setHeight(this.templateDimensions.height * zoomFactor);

    this.canvas.renderAll();
}

The shapes are adjusted independently to the container

  1. 使用第一种导入SVG的方法我做错了什么?我尝试用svgo优化SVG并在Illustrator中编辑它们但没有成功(在fabricjs / kitchensink加载错误)。

  2. 是否存在使用第二种方法锁定容器内SVG的方法?我应该使用其他方法来设置缩放吗?

  3. 我非常感谢您对这些问题的任何帮助。

2 个答案:

答案 0 :(得分:1)

在撰写此问题时,确实存在圆圈和椭圆解析中的错误。圆圈从svg文档中继承宽度和高度,覆盖半径值并替换它们。

此错误已修复, https://github.com/kangax/fabric.js/pull/4637/files#diff-35fc8e842fb0e1e1953d9ba21a292160R189

在rc3和rc4之间引入了这个bug,但现在你可以正常导入路径而不需要预处理SVG,只要你下载了最新版本。

答案 1 :(得分:0)

问题在于SVG文件,circle标签被错误导入FabricJS画布,将对象放在其他位置,甚至在原始viewBox之外。

我在FabricJS Kitchensink中测试了两个版本的SVG:

Screenshot with the differences between SVG imported with <circle> tags and <circle> tags converted to <paths>

我使用svgo来处理所有SVG文件,其中包含convertShapeToPath选项和参数convertArcs设置为true。

{
  "plugins": [
    {"convertShapeToPath": {"convertArcs": true}},
  ]
}

也可以将原始形状转换为Illustrator中的路径,选择对象并为其创建复合路径(菜单对象&gt;复合路径&gt;创建或仅cmd⌘+ 8)。

我在GitHub或Stack Overflow上找不到关于这个问题的问题,所以我真的希望这个解决方案可以帮助其他人面对同样的问题。

非常感谢FabricJS的开发人员和维护人员的出色工作!

SVG文件的要点:

SVG with <circle> tags

SVG with <circle> tags converted to <path>