使用clipPaths导入SVG文件时如何减少Fabric.js的内存使用

时间:2019-06-19 07:20:41

标签: html5-canvas fabricjs

在移动设备上查看时,我正在使用Fabric.js实例遇到WebKit memory limits,并且可以使用一些帮助来确定最佳的攻击计划。

Total canvas memory use exceeds the maximum limit (384 MB).

我的页面导入了包含多个对象的SVG文件。这些对象已分组,并且该组只有一个clipPath。

这里是Example SVG

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="13.889in" height="9.722in" viewBox="0 0 1000 700">
  <defs>
    <clipPath id="clip-path">
      <circle cx="500" cy="350" r="327.5" style="fill: none"/>
    </clipPath>
  </defs>
  <g style="clip-path: url(#clip-path)">
    <circle cx="196.701" cy="90.183" r="29.908" style="fill: #0079d0"/>
    <circle cx="296.246" cy="99.166" r="21.743" style="fill: #0079d0"/>
    <circle cx="354.364" cy="108.67" r="22.485" style="fill: #0079d0"/>
...    

但是,当通过loadSVGFromURL将SVG导入画布时,我的单个clipPath似乎在原始组 中的每个对象重复,并且为每个对象创建了一个新的canvas元素。这些重复的clipPath。

// Create Fabric instance
canvasElement = document.getElementById('canvas');
canvas = this.__canvas = new fabric.Canvas('canvas', {
    enableRetinaScaling: true // default: true
});

// Load SVG image
fabric.loadSVGFromURL('https://dwpmcoaafgla7.cloudfront.net/objects.svg', function(objects, options) {

    // Group Objects
    var obj = fabric.util.groupSVGElements(objects, options);

    // Scale & Place
    var newSize = {
        width: Math.round(canvasElement.scrollWidth),
        height: Math.round((obj.height * canvasElement.scrollWidth) / obj.width)
    };
    var scale = newSize.width / obj.width;
    obj.set({
        scaleX: scale,
        scaleY: scale
    });
    canvas.add(obj);

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

而且,它们很笨重,在内存方面要花一分钱:Screenshot of the web inspector's 'canvas' tab

运行toSVG()也显示了重复的clipPath现在也已附加到每个对象:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1000" height="700" viewBox="0 0 1000 700" xml:space="preserve">
    <desc>Created with Fabric.js 3.1.0</desc>
    <defs></defs>
    <g transform="matrix(0.75 0 0 0.75 500 349.99)" style="">
        <g transform="matrix(1.33 0 0 1.33 -404.37 -346.41)" id="Layer_1" clip-path="url(#CLIPPATH_145)">
            <clipPath id="CLIPPATH_145">
                <circle transform="matrix(1 0 0 1 303.3 259.82)" id="clip-path" cx="0" cy="0" r="327.5"/>
            </clipPath>
            <circle style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,121,208); fill-rule: nonzero; opacity: 1;" cx="0" cy="0" r="29.908"/>
        </g>
        <g transform="matrix(1.33 0 0 1.33 -271.65 -334.44)" id="Layer_1" clip-path="url(#CLIPPATH_146)">
            <clipPath id="CLIPPATH_146">
                <circle transform="matrix(1 0 0 1 203.75 250.83)" id="clip-path" cx="0" cy="0" r="327.5"/>
            </clipPath>
            <circle style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,121,208); fill-rule: nonzero; opacity: 1;" cx="0" cy="0" r="21.743"/>
        </g>
        <g transform="matrix(1.33 0 0 1.33 -194.16 -321.77)" id="Layer_1" clip-path="url(#CLIPPATH_147)">
            <clipPath id="CLIPPATH_147">
                <circle transform="matrix(1 0 0 1 145.64 241.33)" id="clip-path" cx="0" cy="0" r="327.5"/>
            </clipPath>
            <circle style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,121,208); fill-rule: nonzero; opacity: 1;" cx="0" cy="0" r="22.485"/>
        </g>
...

这些重复的画布是否有必要,还是可以以某种方式将其删除?

我意识到我可以禁用enableRetinaScaling在视网膜/高分辨率设备上和/或modify my SVG image by cropping the individual objects along the clipping mask and doing away with the clipping mask altogether上购买一些内存,但是我真的想在诉诸于此之前用尽所有其他选择。

Here's a CodePen

0 个答案:

没有答案