englercj / resource-loader

A middleware-style generic resource loader built with web games in mind.
http://englercj.github.io/resource-loader/
MIT License
424 stars 77 forks source link

Question Load SVG inline #152

Closed Pandan closed 4 years ago

Pandan commented 4 years ago

Hi, This might be a dum question. But I want to load an svg and get the response in xml.

Example: ... <-svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 57.947 57.947"><-path d="M28.947 56.486c15.685-11.277 23.532-21.592 27.222-29.46 4.311-9.193.561-20.589-8.845-24.413C36.268-1.88 28.947 8.486 28.947 8.486S21.678-1.907 10.623 2.588C1.217 6.412-2.533 17.808 1.778 27.001c3.69 7.867 11.484 18.209 27.169 29.485z" fill="#e64c3c"/> ...

But can figure out if its the XhrResponseType that needs to be configured correct. It seems to return an img tag when using the resource-loader What am I missing. loader.add('svgIcon', svgUrl, { xhrType: 'text' }); loader.add('svgIcon', svgUrl, { xhrType: 'document' });

englercj commented 4 years ago

You're probably looking for:

loader.add({ name: svgIcon, url: svgUrl, xhrType: XhrResponseType.Document }); // XhrResponseType.Document == 'document'

In v4 there is no overload of add that takes 3 params: http://englercj.github.io/resource-loader/classes/loader.html#add

Pandan commented 4 years ago

Thanks for the quick answer. I still think I am missing something, maybe fundamental understanding when it comes to loading stuff. 🙈

app.loader.add({
  name: 'svgIcon',
  url: svgUrl,
  xhrType: 'document',
  onComplete: (response) => {
    console.log(response.data); // Returns and img tag,  '<img src="assets/images/svgIcon.svg">'
  },
});

But when using axios

axios(svgUrl).then((response) => {
  console.log(response.data); // Returns svg obj as string, '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 ... etc'
});

Later on I want to parse the svg object and loop through svg paths.

const parser = new DOMParser();
const svgObj = parser.parseFromString(response.data, 'image/svg+xml');
const paths = svgObj.getElementsByTagName('path');

Am I making any sense :D Maybe I should add that I am using the pixi app resource loader

englercj commented 4 years ago

Because SVG defaults to loading as an image. If you want to load it via Xhr you have to tell it use that load strategy instead.

Assuming you're using v4:

loader.add({
    name: 'svgIcon',
    url: svgUrl,
    strategy: Loader.XhrLoadStrategy,
    xhrType: Loader.XhrLoadStrategy.ResponseType.Document,
});

Sorry, forgot to write strategy in my comment above.

Pandan commented 4 years ago

Now its working, thanks for the help.

eric-burel commented 3 years ago

For V3 (shipped with Pixi), this seems to work:

PIXILoader.add({
            // @ts-ignore
            name: iconName,
            url: iconUrl,
            loadType: Resource.TYPE.TEXT,
            xhrType: Resource.XHR_RESPONSE_TYPE.DOCUMENT
          });

In particular, this fixes loading in Firefox. But to be confirmed. I've also raised a question on Stack Overflow to get more insights: https://stackoverflow.com/questions/67414715/load-an-image-with-a-data-uri-with-pixiloader

It still doesn't work, because then Pixi TextureLoader is not ran anymore. How would you then add some logic to catch those request and parse them? How to register a new kind of Loader is very unclear to me

Edit: it seems like a bug, in Chrome I get the right behaviour, but in Firefox now way to actually get the inline SVG, I don't see anything in the network. I'll try to demo that and open a new ticket.

Edit2: for lost googler... there is an issue that prevents SVG with relative width (in percentage) to be handled correctly in Pixi when using Firefox only: https://github.com/pixijs/pixi.js/issues/7473, https://github.com/pixijs/pixi.js/issues/6891. The loading works but the processing wasn't for some reason.