最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Fabric.js loadSVGFromUrl not displaying multiple imported SVGS - Stack Overflow

programmeradmin1浏览0评论

I'm using fabric.js and loading a number of SVG files into it. I have no problem displaying one of these imported files using this code;

fabric.loadSVGFromURL('ico-svg/drink.svg', function(objects, options) {
    var drink = fabric.util.groupSVGElements(objects, options);
    drink.set({left: 80, 
        top: 175, 
        width: 32, 
        height: 32 });
    canvas.add(drink); 
    canvas.calcOffset();
    canvas.renderAll();
}); 

However, when I repeat this code, the page only shows one of the two SVGs, and they actually change upon page refresh - only one icon will show one time, one icon will show the other, on the odd occasion they will both show but one of the SVGs won't display pletely.

To load the other SVG, i'm simply copying the above code and changing the required variables;

fabric.loadSVGFromURL('exporttest.svg', function(objects, options) { 
    var dollars = fabric.util.groupSVGElements(objects, options);
    dollars.set({left: 80, 
        top: 90, 
        width: 350, 
        height: 342 });
    canvas.add(dollars); 
    canvas.calcOffset();
    canvas.renderAll();
}); 
fabric.loadSVGFromURL('ico-svg/drink.svg', function(objects, options) { 
    var drink = fabric.util.groupSVGElements(objects, options);
    drink.set({left: 80, 
        top: 175, 
        width: 32, 
        height: 32 });
    canvas.add(drink); 
    canvas.calcOffset();
    canvas.renderAll();
}); 

Is this something i'm doing wrong? I've read that the library support for loading SVGs from URLs isn't that fantastic - could it be that? Ideally, loading the SVGs from an URL this way or in a similar way is my best option as there are so many, and they are each quite plex and require different positioning.

I'm using fabric.js and loading a number of SVG files into it. I have no problem displaying one of these imported files using this code;

fabric.loadSVGFromURL('ico-svg/drink.svg', function(objects, options) {
    var drink = fabric.util.groupSVGElements(objects, options);
    drink.set({left: 80, 
        top: 175, 
        width: 32, 
        height: 32 });
    canvas.add(drink); 
    canvas.calcOffset();
    canvas.renderAll();
}); 

However, when I repeat this code, the page only shows one of the two SVGs, and they actually change upon page refresh - only one icon will show one time, one icon will show the other, on the odd occasion they will both show but one of the SVGs won't display pletely.

To load the other SVG, i'm simply copying the above code and changing the required variables;

fabric.loadSVGFromURL('exporttest.svg', function(objects, options) { 
    var dollars = fabric.util.groupSVGElements(objects, options);
    dollars.set({left: 80, 
        top: 90, 
        width: 350, 
        height: 342 });
    canvas.add(dollars); 
    canvas.calcOffset();
    canvas.renderAll();
}); 
fabric.loadSVGFromURL('ico-svg/drink.svg', function(objects, options) { 
    var drink = fabric.util.groupSVGElements(objects, options);
    drink.set({left: 80, 
        top: 175, 
        width: 32, 
        height: 32 });
    canvas.add(drink); 
    canvas.calcOffset();
    canvas.renderAll();
}); 

Is this something i'm doing wrong? I've read that the library support for loading SVGs from URLs isn't that fantastic - could it be that? Ideally, loading the SVGs from an URL this way or in a similar way is my best option as there are so many, and they are each quite plex and require different positioning.

Share Improve this question edited Feb 1, 2014 at 17:06 ohmu 19.8k44 gold badges112 silver badges149 bronze badges asked Feb 1, 2014 at 14:08 user3015175user3015175 1631 gold badge3 silver badges17 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 4

I think this was a bug that has been fixed in the library. Current fabricjs. offer a kitchensink demo where you can try code.

http://fabricjs./kitchensink/

copy paste the code below in the execute tab to load 3 svg togheter without any strange issue or taking any precaution.

// clear canvas
canvas.clear();

// remove currently selected object
canvas.remove(canvas.getActiveObject());

fabric.loadSVGFromURL('../assets/1.svg', function(objects, options) { 
    var dollars = fabric.util.groupSVGElements(objects, options);
    canvas.add(dollars); 
    canvas.calcOffset();
    canvas.renderAll();
}); 
fabric.loadSVGFromURL('../assets/2.svg', function(objects, options) { 
    var drink = fabric.util.groupSVGElements(objects, options);
    canvas.add(drink); 
    canvas.calcOffset();
    canvas.renderAll();
});
fabric.loadSVGFromURL('../assets/3.svg', function(objects, options) { 
    var drink = fabric.util.groupSVGElements(objects, options);

    canvas.add(drink); 
    canvas.calcOffset();
    canvas.renderAll();
}); 

I actually do this as well, where a user can select any number of SVG files to load and later e back to edit their work. When they e back, I had the same issue while trying to reload the multiple files. In my case, I am actually building an array of objects that hold the svg url along with other useful pieces of information. This allowed me to load them into a stack (most suiting for my loading order, though you could easily implement it with a queue) and then pop them off one at a time.

var loadingLayerStack = [url1, url2, url3];

function ProcessLayerLoading()
{
    var layerUrl = loadingLayerStack.pop();
    DrawSvgToCanvas(layerUrl);
}

function DrawSvgToCanvas(url)
{
    fabric.loadSVGFromURL(url, function(objects, options) {
        var obj = fabric.util.groupSVGElements(objects, options);


        // ...any code for special handling of the loaded object


        // put object on the canvas
        canvas.add(obj);

        // get the next image
        ProcessLayerLoading();
    });
}

It is noteworthy to point out that I have the setting to enable Rendering when an object is added. So that canvas.add call also takes care of the initial rendering for me.

Hope this helps you somehow. :)

I just ran into this same problem, after seeing your post I decided to dig in to it a bit further myself. It turns out to be due to a scope issue in the onComplete callback within loadSVGFromURL. The problem stems from not isolating the url to a single scope; making multiple back-to-back calls results in the last url always being used when onComplete fires. As a workaround you could either chain your SVG loads or just make an ajax request yourself and load it using loadSVGFromString instead.

I'm learning fabric seems to be full of these bugs, errr, gotchas :(

Edit

I spoke too soon, loadSVGFromString suffers from the same weakness, it does not work asynchronously. That being said chaining is the most obvious work-around.

fabric.loadSVGFromURL() fetches the SVG via XmlHttpRequest. If you wait for each request to plete you can load multiple. Which means you need a tool for making and posing asynchronous promises in JavaScript. Check out q. https://github./kriskowal/q

发布评论

评论列表(0)

  1. 暂无评论