Canvas库处理SVG和SVG库处理SVG的方式有什么区别?

时间:2014-11-22 00:18:06

标签: javascript canvas svg webgl

我对在浏览器中探索图形用户界面非常感兴趣。我非常喜欢.SVG文件有很多原因,主要是它们可扩展,可以在像Illustrator这样的程序中轻松制作。我喜欢的另一件事是,在许多库(例如Snap.svg)中,可以选择单个图层(就像更复杂形状的圆形路径一样)。

但是,我也经常使用粒子并且要绘制许多对象。因为我做了对音乐作出反应的事情,所以我需要尽可能绝对最快的库(用很多物体保持高FPS数)。

在查看了webGL和SVG以及画布之后,我可以看到webGL显然是绘制图片之类的东西最快的,但是我看不到任何能够使用webGL并访问本机svg库所具有的相同Path信息的库

有人可以向我解释一下“native”svg库和使用canvas元素的库(例如paper.js fabric.js)与“svg解析器”之间的区别吗? (我甚至不知道svg解析器是什么)。

似乎库以某种方式将项目绘制到画布上,我相信它会将它们变成栅格(失去svgs的可伸缩性和分辨率独立性),我不确定svgs的各个层/路径是否仍然可以被选中(因为它们可以在像Snap这样的库中)。

我也很想知道为什么没有基于webGL的svg库。

谢谢

1 个答案:

答案 0 :(得分:19)

以下是快速细分(免责声明:我是Fabric.js的作者)

SVG库

Raphael.js,Bonsai.js,svg.js,Snap.svg等。

这些使用SVG作为渲染图形的基础技术。这是矢量图形。它们都是抽象和“网关”,允许您执行类似的操作(来自Bonsai的示例):

var shape1 = new Rect(10,10,100,100).attr({fillColor: 'red'});
var group = new Group();
group.addChild(shape1);

stage.addChild(group);

得到这个:

<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>

反过来呈现如下:

img

这些库允许您通过更高级别的抽象间接使用SVG节点,属性和值。

画布库

Fabric.js,Paper.js,Kinetic.js等

这些使用canvas作为渲染图形的基础技术。这是光栅图形。它们也是抽象和“网关”,允许您执行类似的操作(例如来自Fabric):

var rect = new fabric.Rect({ 
  left: 100, 
  top: 100, 
  width: 100, 
  height: 100, 
  fill: 'red'
});
canvas.add(rect);

让它呈现如下:

img

由于这些库是基于画布的,因此该文档只有<canvas>个元素。其他所有内容都用(低级)代码在内部表示,如下所示:

var canvasEl = document.getElementById('c');    
var ctx = canvasEl.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(100, 100, 100, 100);

具有SVG解析的画布库

Fabric.js,canvg等

这些是Canvas库的子集,但支持解析SVG 。这意味着库可以像这样使用SVG:

<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>

并像这样呈现:

img

这基本上是SVG - &gt;画布转换。它也是矢量 - &gt;伪栅格转换。它是伪栅格的原因是因为质量没有损失(至少在Fabric的情况下)。在变换矢量SVG时,Fabric会从中生成虚拟和非光栅对象,然后可以在任何大小,角度,位置等处渲染该对象,而不会降低质量。它甚至可以导出回SVG。只有在画布上渲染时,它才会成为光栅图形。

WebGL库

Three.js,Babylon.js,c3DL,Pixi.js等。

这些是使用WebGL渲染上下文而不是“2d”上下文的Canvas库(基于<canvas>,而不是SVG)的超集:

// webgl canvas libraries
canvas.getContext('webgl');

// non-webgl canvas libraries
canvas.getContext('2d');

与非WebGL画布库相比,WebGL画布库使用完全不同的API通过画布绘制图形。他们也常常支持“2d”上下文,作为后备场景。

WebGL 2d vs 3d

WebGL库也可以分为2d和3d--在2d或3d输出中“专门化”。最流行的3d webgl库示例是Three.js和2d - Pixi.js。

作为旁注,一旦我们在Fabric.js中添加对WebGL渲染器的支持,该库将从“具有SVG支持的画布库”变为“具有SVG支持的具有webgl功能的画布库”:)