Manifest

Phaser & SVG Files

Recommended Posts

I'm having issues loading SVG files into my game. I have done a straight swap of my old .png background and replaced it with a properly drawn and vectorized .svg file. When I display this on my 1280x720 canvas, the image only takes up a small portion of the space, where before it filled it properly. Stretching it by manually adjusting the width/height properties only causes it to stretch horribly, not the way that a vectorized file should. Opening the file in Illustrator confirms that the file itself is fine.

 

Is there any special trick to getting SVGs to work with Phaser?

Share this post


Link to post
Share on other sites

Yep. Literally changed the extension in image.load from .png to .svg (and converted the file externally). I'd say the image was about 1/3 of the intended size. Looked pretty horrible though - the colours were fine, but it was rather pixelated.

Share this post


Link to post
Share on other sites

Just my two cents,

 

It would be great if there was some type of on the fly svg to canvas converter that would run after the game determined the display resolution of the device.  It would reduce the need for graphic assets of different  dimensions to support low end and HD displays. It should also reduce overall game size and improve network downloads.

 

Optionally, it could allow for players to mod svg attributes prior to game play such as color, size, etc.

 

Some links I came across regarding potential advantages:

 

http://www.html5rocks.com/en/tutorials/svg/mobile_fundamentals/

http://stackoverflow.com/questions/3768565/drawing-a-svg-file-on-a-html5-canvas

http://stackoverflow.com/questions/5495952/draw-svg-on-html5-canvas-with-support-for-font-element

and using the older canvg:

http://getcontext.net/read/svg-sprites-in-canvas

and update without canvg:

http://getcontext.net/read/svg-images-on-a-html5-canvas

 

Some really cool ideas out there! :)

Share this post


Link to post
Share on other sites

I just tested on 2.0.7  that it is possible to load svg images.  The sprites created from them can be scaled up or down without pixelation or loss of detail which is cool, but does that mean they are not being stored internally as bitmap?

Or does scaling repaint to bitmap from vector?

I also checked that it works in CANVAS and WEBGL mode for chrome, firefox and safari.

Need to check IE.

Share this post


Link to post
Share on other sites

Correction:   Safari only can show in CANVAS mode, WEBGL comes up blank even after enabling WebGL through the developer menu.

 

The console is showing a security error which may or not be related:

SecurityError: DOM Exception 18: An attempt was made to break through the security policy of the user agent.   phaser.js:5778

Share this post


Link to post
Share on other sites

That line number is part of PIXI code:

            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);

 

I'm guessing it is texture.source that is triggering the security error, my test sprite object 

(test.texture.baseTexture.source) shows:   <img name="test" src="test.svg">

 

So some setting in the browsing is prohibiting PIXI from accessing the svg file, but I have no idea where to find it.

Share this post


Link to post
Share on other sites

I just tested on 2.0.7  that it is possible to load svg images.  The sprites created from them can be scaled up or down without pixelation or loss of detail which is cool, but does that mean they are not being stored internally as bitmap?

 

Do you have a demo of this? I've no idea whatsoever how or why this is working, but it absolutely should not. Previously people have managed to get SVG to work for sprites, but upon scaling they've turned out to be bitmap representations generated by the browser.

Share this post


Link to post
Share on other sites

Hi lewster,

 

So I tested again a while ago on chrome browser using my last modified svg file from last night. This time, the image seemed to scale as a bitmap with pixelation. So thinking something wrong with my eyes last night, I tried another svg sample, and lo and behold, the scaling as vector showed up again.  I tried again creating sprites from both the first svg and second svg files, and both scaled as vector.

Then I tried the first svg file again, this time it scaled as vector.  Since the first time, I have not been able to reproduce scaling as bitmap on chromium browser.

 

Further testing show that chromium, safari, ie9 scale as vector, while firefox scales as bitmap. 

 

Attached are my sample files.

 

 

 

 

Share this post


Link to post
Share on other sites

@ivanix - Were you able to get the code examples that you've attached to work in IE. I noticed you mentioned that IE9 scales as vector, however I'm not seeing anything show up when I test in IE while loading SVG assets directly into the sprites.

 

- Chris

Share this post


Link to post
Share on other sites

@ivanix - Correction, it looks like the game is blank only in IE11 on Windows 7 - by any chance, are you running into this issue as well?

 

Also, @lewster32 - I often see mods commenting on how SVGs shouldn't work when users have success loading them into their games as sprites. Loading SVGs directly into my game is actually a very important aspect as there is a lot of scaling, however I'm concerned about the surprise of the moderators regarding this and fear that this is just a serendipitous bug that will eventually stop working in the future?

Share this post


Link to post
Share on other sites

I'd not rely on it for scaling my assets, put it that way. The reason is simple, pixi works with bitmaps in most cases. It converts assets to bitmap data which either gets uploaded to the GPU as textures and displayed on quads (basically rectangles made of two triangles) or if using canvas, gets copied as pixel data to the display surface (in this case a canvas instance) - at no point should the engine directly deal with the original vector shapes in your SVG files. Quite a lot of work has gone into providing a cross-platform Graphics object which does all kinds of tricks with triangulation and so on to replicate relatively basic shape drawing in both webGL and canvas, and that technically could be where SVG files could be in some way used, keeping their vector nature, but this would probably be a large undertaking to ensure unity between the two rendering pipelines.

 

Top and bottom of it is that we don't know why SVG works, but can only assume that the browser at some point is turning the SVG to pixels before passing it to Phaser/pixi, otherwise there's no way this could work. I'm highly sceptical that the assets are kept as vector, and I think at best they're just being imported into the engine at a high resolution so the scaling never becomes obvious, but I definitely will do some tests on this to see what on Earth is going on - because the test posted above here seems to be doing exactly what we can't seem to fathom is possible!

Share this post


Link to post
Share on other sites

Interestingly, if I tween the sprite/image created with your SVG, the text in it looks like it's continually being re-rendered, as text and characters shift about to respect the change on font size. This leads me to believe that the SVG is being re-drawn from scratch every frame. Also, cacheAsBitmap does not work on the image at all.

Share this post


Link to post
Share on other sites
@rgbchris,

Thanks for catching that. I had not yet tested on ie11 until now. 

 

I see the issue on my window 8.1  with ie 11.0.9600.1663.

There is a bug reported, not sure if its related: 


If it is, I am not sure what (sub)version will fix it.  

 


Which suggests that ie11 defaults to "compatibility view" enabled so its acting as ie7 which cannot render svg?

 

My ie11 also fails the mozilla svg to canvas demo: 


Share this post


Link to post
Share on other sites

@lewster32,

 

I agree with what your are saying. Even if they can, Phaser/Pixi should not be redrawing from the svg everytime, that would incur a performance hit and that does seems to be what's happening when I test on my android phone with chrome browser and renderType set to CANVAS.

 

So I am going to try see if we can have a  hidden canvas staging area during preload that will allow us to render svg assets to the max desired resolution for the given device. Then from the canvas staging feed the bitmaps over the phaser/pixi.

No idea what the memory penalty would be for this on mobile.

Share this post


Link to post
Share on other sites

Ok further investigations seem to show that if you use WebGL or if you tint the object to any value other than 0xffffff, or if you change its blendMode, it becomes a bitmap representation of the SVG object. Additionally, in canvas changing the blendMode seems to affect the whole scene, and it quickly fades to black/white depending on whether you use multiply or add.

 

After doing some digging around I've come up with this, which seems to suggest that rendering SVG to a canvas element is entirely normal behaviour: http://stackoverflow.com/questions/5495952/draw-svg-on-html5-canvas-with-support-for-font-element

 

Also http://stackoverflow.com/questions/3768565/drawing-a-svg-file-on-a-html5-canvas

 

I'm really confused now... this is a very interesting topic though.

Share this post


Link to post
Share on other sites

When Phaser loads an svg file it sets it as the data source for an Image tag. You can render these to a canvas quite happily and have been able to for a couple of years I believe, however it is absolutely not fully cross-browser compatible and browsers will do different things depending on the svg data. Some of them will cache the svg as a bitmap representation as the image data, where-as I've seen others do the render at draw time (which must be pretty expensive). I don't know why it changes, but I suspect at some point the browser considers it too complex so caches it as a bitmap.

 

If this happens on load (when assigned to the Image element) then it should technically work fine in WebGL and Canvas. If it happens at run-time then I expect it to be Canvas only. I'm also curious what size the Image is rendered at if done on load - if it's always done at render time then it knows the dimensions from the drawImage call.

 

I'll experiment a bit more and try to get to the bottom of this, but honestly for genuine Phaser support of svg it would have to work on the basis of specifying the svg to load and a size to render it at, and then doing so to a hidden canvas which becomes the texture. Without direct support like that I'd say you're utterly at the whim of the browser, and all the variations that may entail.

Share this post


Link to post
Share on other sites

Hello,

 

I think it will be a very nice feature to have in phaser, the svg support, because it makes the game to scale with more pixel-quality.

In the mean time, I think another very nice feature could be to implement an idea similar to icons (.ico), something like:

 

game.load.image('enemy', ['imgs/enemy16.png', 'imgs/enemy32.png', ....])

 

So, in this way phaser renders enemy16.png or enemy32.png in dependence of the scale/resolution of the game.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.