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

Sta*_*tec 7 javascript svg canvas webgl

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

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

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

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

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

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

谢谢

kan*_*gax 19

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

SVG库

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

这些使用SVG作为渲染图形的基础技术.这是矢量图形.它们都是抽象和" 网关 ",允许你执行这样的事情(来自盆景的例子):

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

stage.addChild(group);
Run Code Online (Sandbox Code Playgroud)

得到这个:

<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>
Run Code Online (Sandbox Code Playgroud)

而这反过来呈现如下:

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);
Run Code Online (Sandbox Code Playgroud)

并让它呈现如下:

IMG

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

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

具有SVG解析的Canvas库

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>
Run Code Online (Sandbox Code Playgroud)

并像这样呈现:

IMG

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

WebGL库

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

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

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

// non-webgl canvas libraries
canvas.getContext('2d');
Run Code Online (Sandbox Code Playgroud)

与非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功能的画布库":)