SVG到backgroundImage和overlayImage

时间:2018-06-28 14:28:12

标签: fabricjs

我正在从布料画布内的URL加载SVG。我过滤了SVG对象,将它们分为2组:第一个用作背景图像,另一个用作覆盖图像。

这是代码:

fabric.loadSVGFromURL(
  site_url,
  (objects,options) => {
    const background = fabric.util.groupSVGElements(objects.filter(i => i.id.includes('background')), options)
    const overlay = fabric.util.groupSVGElements(objects.filter(i => i.id.includes('overlay')), options)
    background.scaleToWidth(canvas.getWidth())
    canvas.setBackgroundImage(background, () => canvas.renderAll())
    overlay.scaleToWidth(canvas.getWidth())
    canvas.setOverlayImage(overlay, () => canvas.renderAll())

  }, null, { crossOrigin: 'anonymous' },
)

这是预期的结果:

enter image description here

这不起作用。好吧,实际上,只有在backgroundoverlay中的所有对象共享相同的大小时,这才起作用。但是由于他们没有这样做,所以实际上导致:

Background (purple) and shadow

现在,如果我将代码更改为:

fabric.loadSVGFromURL(
  site_url,
  (objects,options) => {
    const background = fabric.util.groupSVGElements(objects, options)
    background.scaleToWidth(canvas.getWidth())
    canvas.setBackgroundImage(background, () => canvas.renderAll())

  }, null, { crossOrigin: 'anonymous' },
)

一切正常,将产生y第一张图像。我很确定它来自scaleToWidth的两次使用,因此导致了backgroundImage和overlayImage的大小不同,但是我不知道如何在缩放overlayImage和backgroundImage的同时保持我的SVG,我不认为在文档中看到关于loadSVGfromURL处理它的任何内容。

1 个答案:

答案 0 :(得分:0)

好吧,如果有人挣扎,则必须确保用于背景和覆盖的对象共享相同的大小。如果没有,则必须自己设置比例:

fabric.loadSVGFromURL(
  svg_url,
  (objects, options) => {
    const loadedBackObjects = fabric.util.groupSVGElements(objects.filter(o => o.id.split(' ').includes('back')), options)

    const ratio1 = this.props.size / options.width
    canvas.setBackgroundImage(
      loadedBackObjects,
      () => {
        canvas.selection = true
        const loadedFrontObjects = fabric.util.groupSVGElements(objects.filter(o => o.id.split(' ').includes('front')), options)
        const ratio2 = this.props.size / loadedFrontObjects.width
        canvas.setOverlayImage(loadedFrontObjects, () => {
          if (canvas.overlayImage._objects) {
            canvas.overlayImage._objects.filter(i => i.id.split(' ').includes('Heather')).map((i) => {
              i.set({ opacity: this.props.variation.heather ? 1 : 0 })
            })
          }
        }, {
          scaleX: ratio2,
          scaleY: ratio2,
          top: loadedFrontObjects.top * ratio1,
          left: loadedFrontObjects.left * ratio1,
        })
        canvas.renderAll.bind(canvas)
      }, {
        scaleX: ratio1,
        scaleY: ratio1,
        top: loadedBackObjects.top * ratio1,
        left: loadedBackObjects.left * ratio1,
      },
    )
    canvas.renderAll()
  }, null, { crossOrigin: 'anonymous' },
)