Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render SVG with PixiJS?

I'm trying to make a game using SVG images for scalability and for procedurally making physical objects from them (see matter.js for how).

The problem I'm having is if I load 2 different SVG textures and then render them, the second has the first layered underneath it.

This doesn't happen with raster images and doesn't happen with the canvas options, only with WebGL.

Is there a way to stop this or am I doing the SVGs wrong?

var renderer = PIXI.autoDetectRenderer(
    window.innerWidth, 
    window.innerHeight, 
    {
        backgroundColor : 0xffffff,
        resolution:2
    }
);

// add viewport and fix resolution doubling
document.body.appendChild(renderer.view);
renderer.view.style.width = "100%";
renderer.view.style.height = "100%";

var stage = new PIXI.Container();

//load gear svg
var texture = PIXI.Texture.fromImage('https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Gear_icon_svg.svg/2000px-Gear_icon_svg.svg.png');
var gear = new PIXI.Sprite(texture);

//position and scale
gear.scale = {x:0.1,y:0.1};
gear.position = {x:window.innerWidth / 2,y:window.innerHeight / 2};
gear.anchor = {x:0.5,y:0.5};

//load heart svg
var texture2 = PIXI.Texture.fromImage('https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/Love_Heart_SVG.svg/2000px-Love_Heart_SVG.svg.png');
var heart = new PIXI.Sprite(texture2);

//position and scale
heart.scale = {x:0.1,y:0.1};
heart.position = {x:window.innerWidth/4,y:window.innerHeight / 2};
heart.anchor = {x:0.5,y:0.5};

//add to stage
stage.addChild(gear);
stage.addChild(heart);

// start animating
animate();
function animate() {
    gear.rotation += 0.05;

    // render the container
    renderer.render(stage);
    requestAnimationFrame(animate);

}
<script src="https://github.com/pixijs/pixi.js/releases/download/v4.8.2/pixi.min.js"></script>
like image 423
Dakun Skye Avatar asked Jul 29 '15 21:07

Dakun Skye


2 Answers

Well, this example seems to work pretty well!

var beeSvg = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/bee.svg";
beeTexture = new PIXI.Texture.fromImage(beeSvg, undefined, undefined, 1.0);
var bee = new PIXI.Sprite(beeTexture)

See more at: https://codepen.io/osublake/pen/ORJjGj

like image 188
sparkyspider Avatar answered Nov 08 '22 06:11

sparkyspider


So I think you're mixing concepts a bit.

SVG is one thing and WebGL is another. SVG's are rendered by the browser and you can scale them up or down without losing quality/resolution or whatever you want to call it.

This characteristic however is not possible in WebGL because WebGL rasterises images. A bit like taking a screenshot and putting it in a layer on Photoshop. You can manipulate that image, but u can't scale it without starting to see the pixels.

So short answer is, you can't use SVG's in a WebGL hoping to make your graphics "scale".

In regards to your example above, the result is the expected.

You are loading 2 png textures and overlaying them.

like image 39
andrevenancio Avatar answered Nov 08 '22 06:11

andrevenancio