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

Loading SVG assets in IE11 #111

Closed guigzz closed 6 years ago

guigzz commented 6 years ago

Hi,

This loader, used via Pixi.js, dosn't seem to be able to load svg assets in IE11.

Here is a pen that demonstrates the issue : https://codepen.io/guigzz/pen/zRWjvw (left is without the loader, using texture fromImage directly, and right is with the loader)

I know it's about IE but... if it cannot be fixed, is there any workaround that could be used if I really need this feature ? Thanks in advance.

Cheers

englercj commented 6 years ago

I investigated this, and it is due to a bug in PIXI.BaseTexture.loadSource(). Basically it doesn't support receiving a completely loaded SVG Image.

This line needs to update the image type, just like this line does. In fact the onload handler and the complete check block look so similar, they probably should just call the same function.

Anyway that causes the issue here. Because the imageType doesn't get updated (because the image has already loaded) the "load svg" path in pixi never happens and therefore the texture is never correct.

I opened an issue on the pixi issue tracker for you at pixijs/pixi.js#4704. Good luck!

guigzz commented 6 years ago

Thanks a lot man !

guigzz commented 6 years ago

@englercj so I looked a bit further into this issue recently and here are a few thoughts I came up with :

1 - I tried adding the _updateImageType to force the update but this doesn't seem to work at all.

2 - Indeed as you have pointed out, the root of the problem comes from the width and height of the image not set when on IE. I tried to manually add the size in the BaseTexture file and it does load properly after that.

What I don't see is what I could override or extend to be able to set the size on the source before it arrives in BaseTexture.

The obvious answer would be to actually set it right after the creation of the object, in this resource-loader (Resource.js). Is it something that could be done or not ? Do we potentially have access to all needed information ? could we kind-of parse the SVG string juste before the creation of the Image object to extract the width and height attributes ?

Another solution could be to pass some additional width and height to the Pixi.Loader while on IE and modify it to use these values for the Texture creation ? Could it be done by writing a middleware similar to what already exists ? (I thought about it but didn't manage see how could I do it).

Do you any hints about all this ? 😄

Thank you in advance, I know this is not a first-class issue but I really need to have my app working on IE11 😃

Cheers

englercj commented 6 years ago

I think if someone solved pixijs/pixi.js#4704 in the way I suggest it should fix your problem. If that doesn't fix it I'm not really sure, would need to dig for a while more but I don't really have time to :(

guigzz commented 6 years ago

I totally understand you have no time for this ;)

Just to be sure, when you say "the way I suggest" in your message, it's the fix involving the addition of a call to _updateImageType() ? Because this does nothing apparently when I try it, and I'm not really sure how it could fix the size issue, but I might not fully understand how BaseTexture works after all...

Could you confirm that the fix should be with the _updateImageType() ?

And thank you very much for your time ! 👍

englercj commented 6 years ago

It doesn't just need to be called, it needs to be called at the spot that I mentioned. Just after that spot there is a check to see if it is SVG and if it is, to do all the work necessary to set the width/height (see here).

This check fails because the imageType is not set.

guigzz commented 6 years ago

Yes of course, I tried to call _updateImageType at the spot you mentionned. No success.

Actually, if I force the image type to be svg and I remove all the check for image type on my way, I land on the _loadSvgSourceUsingXhr() function and this is where IE get stucks. Judging by all the comments in this function, IE breaks because of its "good old" data inlining bug (see here).

Actually, I found a temp dirty workaround that consists of forcing source.width and source.height at the beginning of the loadSource() function, and then the code never goes into the complete callback, so never fails in the loadSvgSourceUsingXhr function... And it displays the texture as we would expect...

So, considering that the IE bug involved in the loadSvgSourceUsingXhr will never be fixed, the "real" problem appears to be the missing width and height on the source object that arrives in the loadSource function. Would you agree with that or do you see anything that I am missing ?

Cheers.

englercj commented 6 years ago

Honestly don't know, I'd have to debug on IE and see what in pixi is failing. Best bet to fix your issue is see why the code in _loadSvgSourceUsingXhr() isn't working for you, because it should just be running a regex on the loaded XML string got back from XHR. I'd breakpoint in the load callback and walk through _loadSvgSourceUsingString() to see what is up.