【问题标题】:Can't properly import SVGs to canvas无法将 SVG 正确导入画布
【发布时间】:2018-06-28 19:09:28
【问题描述】:

我在将 SVG 导入画布并将 setZoom() 与 FabricJS 一起使用时遇到问题。我使用的是“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- 新面料。图片

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 锁定在容器内的方法?我应该使用其他方法来设置缩放吗?

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

【问题讨论】:

  • 发生了什么很奇怪,这将有助于获得 SVG
  • 谢谢@AndreaBogazzi,我只是回答我的问题。问题出在 SVG 文件上,<circle> 标签被错误地导入画布。将它们转换为 <paths> 效果很好。我应该在 GitHub 上打开这个问题吗?
  • 存在一个 inport svg 问题,它报告了渐变和圆。标题具有误导性。已修复。
  • 如果您可以复制和解释它们,通常会为错误打开问题。

标签: javascript canvas svg fabricjs


【解决方案1】:

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

这里已经修复了这个错误, https://github.com/kangax/fabric.js/pull/4637/files#diff-35fc8e842fb0e1e1953d9ba21a292160R189

在 rc3 和 rc4 之间引入了该错误,但现在您可以在不预处理 SVG 的情况下正常导入路径,前提是您下载了最新版本。

【讨论】:

  • 谢谢@AndreaBogazzi,我使用的是通过npm安装的2.0.0 rc4版本。
  • 还没有在 npm 上
【解决方案2】:

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

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

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

我使用svgo 处理所有带有convertShapeToPath 选项的SVG 文件,并将convertArcs 参数设置为true。

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

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

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

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

SVG 文件要点:

SVG with <circle> tags

SVG with <circle> tags converted to <path>

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 2014-10-08
    • 2017-06-16
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-28
    • 1970-01-01
    相关资源
    最近更新 更多