I am very interested in exploring graphical user interfaces in the browser. I really like .SVG files for many reasons, mainly that they are scalable and can be easily made in programs like Illustrator. The other thing I like is that in many libraries (such as Snap.svg) the individual layers can be selected (like just the circle path of a more complex shape).
However, I also frequently use particles and have many objects to draw. Because I do things that react to music I need the absolute fastest library possible (to maintain a high FPS count with many objects).
After looking at webGL and SVG and canvas, I can see that webGL is obviously the fastest for drawing things such as pictures, but I see no libraries that are able to use webGL and access the same Path information that native svg libraries have.
Could someone explain to me what the difference between "native" svg libraries and libraries that use the canvas element (such as paper.js fabric.js) with "svg parsers"? (I don't even really know what an svg parser is).
It seems that the libraries somehow draw the items to the canvas, which I believe would turn them into raster (losing the scalability and resolution independence of svgs) and I am not sure that the individual layers / paths of the svgs could still be selected (as they can be in libraries like Snap).
I would also love to know why there are no webGL based svg libraries.
Thank you
I am very interested in exploring graphical user interfaces in the browser. I really like .SVG files for many reasons, mainly that they are scalable and can be easily made in programs like Illustrator. The other thing I like is that in many libraries (such as Snap.svg) the individual layers can be selected (like just the circle path of a more complex shape).
However, I also frequently use particles and have many objects to draw. Because I do things that react to music I need the absolute fastest library possible (to maintain a high FPS count with many objects).
After looking at webGL and SVG and canvas, I can see that webGL is obviously the fastest for drawing things such as pictures, but I see no libraries that are able to use webGL and access the same Path information that native svg libraries have.
Could someone explain to me what the difference between "native" svg libraries and libraries that use the canvas element (such as paper.js fabric.js) with "svg parsers"? (I don't even really know what an svg parser is).
It seems that the libraries somehow draw the items to the canvas, which I believe would turn them into raster (losing the scalability and resolution independence of svgs) and I am not sure that the individual layers / paths of the svgs could still be selected (as they can be in libraries like Snap).
I would also love to know why there are no webGL based svg libraries.
Thank you
Share Improve this question asked Nov 22, 2014 at 0:18 StartecStartec 13.2k28 gold badges107 silver badges168 bronze badges 7- The canvas is doesn't handle SVG at all. It's a raster-based drawing surface; once data's painted on it, that's it, it is now pixels. WebGL is one of the modes that the canvas can use - for 2d raster graphics there's the Canvas2D API, for 3d raster graphics it's WebGL. – Mike 'Pomax' Kamermans Commented Nov 22, 2014 at 0:22
- 1 Right but libraries like paper.js and fabric.js use SVG, and are able to parse it, presumably but someone converting the SVG to canvas pixels? – Startec Commented Nov 22, 2014 at 0:25
- Paper.js uses the canvas to draw, but can track shapes, which it can built off of SVG input, and which it knows how to serialize back to an SVG output. – Mike 'Pomax' Kamermans Commented Nov 22, 2014 at 0:28
- So, the way that particular library handles it is it takes an svg -> turns into pixels -> draws in canvas (displays) but what do you mean serialize back into SVG output? – Startec Commented Nov 22, 2014 at 0:33
- Why would anyone write a WebGL SVG library? Every browser that supports WebGL already supports SVG. – user128511 Commented Nov 22, 2014 at 0:53
1 Answer
Reset to default 26Here's quick breakdown (disclaimer: I'm the author of Fabric.js)
SVG libraries
Raphael.js, Bonsai.js, svg.js, Snap.svg, etc.
These use SVG as the underlying technology to render graphics. This is vector graphics. They are both abstractions and "gateways" that allow you to execute something like this (example from Bonsai):
var shape1 = new Rect(10,10,100,100).attr({fillColor: 'red'});
var group = new Group();
group.addChild(shape1);
stage.addChild(group);
and get this:
<svg data-bs-id="0" width="796" height="796" class=" bs-1416663517803-1" viewBox="-0.5 -0.5 796 796">
<defs></defs>
<g data-bs-id="1087">
<g data-bs-id="1089">
<path data-bs-id="1088" d="M 0 0 l 100 0 l 0 100 l -100 0 Z"
fill="rgba(255,0,0,1)"
data-stroke="rgba(0,0,0,1)"
transform="matrix(1,0,0,1,10,10)"
stroke-width="0"
stroke-dashoffset="0"></path>
</g>
</g>
</svg>
which in turn renders like this:
These libraries allow you to work with SVG nodes, attributes, and values indirectly, via a higher-level abstraction.
Canvas libraries
Fabric.js, Paper.js, Kinetic.js, etc.
These use canvas as the underlying technology to render graphics. This is raster graphics. They are also both abstractions and "gateways" that allow you to execute something like this (example from Fabric):
var rect = new fabric.Rect({
left: 100,
top: 100,
width: 100,
height: 100,
fill: 'red'
});
canvas.add(rect);
and have it rendered like this:
Since these libraries are canvas-based, the document will only have <canvas>
element. Everything else is represented internally with (lower-level) code like this:
var canvasEl = document.getElementById('c');
var ctx = canvasEl.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(100, 100, 100, 100);
Canvas libraries with SVG-parsing
Fabric.js, canvg, etc.
These are a subset of Canvas libraries, but with support of parsing SVG. This means a library can take SVG like this:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800" height="700" xml:space="preserve">
<rect x="10" y="10" width="100" height="100" stroke="blue" fill="purple" fill-opacity="0.5" stroke-opacity="0.8"/>
</svg>
And render it like this:
This is essentially SVG -> canvas conversion. And it's also vector -> pseudo-raster conversion. The reason it's pseudo-raster is because there's no loss in quality (at least in case of Fabric). When transforming vector SVG, Fabric makes a virtual and non-raster object out of it, and that object can then be rendered in any size, angle, position, etc. without loss of quality. It can even be exported back to SVG. Only when rendered on canvas, then it becomes raster graphics.
WebGL libraries
Three.js, Babylon.js, c3DL, Pixi.js, etc.
These are a superset of Canvas libraries (based on <canvas>
, not SVG) that use WebGL rendering context rather than "2d" context:
// webgl canvas libraries
canvas.getContext('webgl');
// non-webgl canvas libraries
canvas.getContext('2d');
WebGL canvas libraries use a completely different API for drawing graphics via canvas comparing to non-WebGL canvas libraries. They also often have support for "2d" context, as a fallback scenario.
WebGL 2d vs 3d
WebGL libraries can also be categorized into 2d and 3d — those "specializing" in 2d or 3d output. The most popular example of 3d webgl library is Three.js and 2d — Pixi.js.
As a side note, once we add support for WebGL renderer in Fabric.js, the library will go from "canvas library with SVG support" to "webgl-capable canvas library with SVG support" :)