数据渲染--->canvas 和 SVG实现对比

数据渲染技术对比

选择什么作为承载我们可视化结果的容器,同时选择什么样的绘制技术来渲染这些数据。往往面对不同的可视化需求,不同量级的数据,我们需要选择不同的渲染技术,渲染技术的选择和学习也是其中一个难点。毫无疑问,作为前端这个领域,承载我们可视化的结果容器就是现代浏览器。在现代浏览器中可以完成可视化的绘制技术至少有4个:HTML、Canvas2D、SVG、WebGL。HTML 的绘制不够灵活,WebGL 主要针对三维场景的可视化(虽然也可以进行二维可视化,我们之后会了解到),所有主流的 2D 可视化的绘制技术主要有两种: Canvas2D 和 SVG。
Canvas2D 和 SVG 的使用方式不同,针对的场景也不同,接下来我们就分别说说。

Canvas2D

通过绘制一个矩形和 hello world 来看看 Canvas2D 的使用方式。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script>
      // 获得 canvas 容器元素
      const canvas = document.getElementById("canvas");

      // 设置 canvas 的样式宽高
      // 样式宽高决定了 canvas 在画布上呈现的大小
      canvas.style.width = 400 + "px";
      canvas.style.height = 200 + "px";

      // 设置 canvas 画布宽高
      // 这个宽高是可以绘制区域的大小
      // 样式宽高是默认等于画布宽高的
      canvas.width = 400;
      canvas.height = 200;

      // 获得绘制的上下文
      // 之后的 API 都是通过调用 context
      const context = canvas.getContext("2d");

      // 绘制一个矩形
      context.fillStyle = "red"; // 设置填充颜色
      context.strokeStyle = "yellow"; // 设置边框的颜色
      context.lineWidth = 10; // 设置边框的宽度
      context.strokeRect(0, 0, 100, 100); // 绘制边框
      context.fillRect(5, 5, 95, 95); // 绘制填充颜色
      // 绘制一段文字
      context.fillStyle = "black"; // 设置文字的颜色
      context.font = "25px PingFangSC-Regular, sans-serif"; // 设置文字的大小和字体
      context.fillText("hello world", 150, 100); // 绘制文字
    </script>
</body>
</html>

当然 Canvas2D 的能力肯定不止绘制矩形和文字,更多的基本图形:圆形、线段和路径这些我们之后会涉及,但绘制方式都大同小异。首先,我们设置一些绘制的样式,然后调用绘制命令来绘制拥有这些样式的视觉元素。所以其实 Canvas 的 API 主要分为两类,一类是设置状态的 API: context.fillStyle = 'red' ,另一类是绘制的 API:context.fillRect(0, 0, 10, 10) 。

SVG

接下来,我们再看看第二种绘图方式:SVG(Scalable Vector Graphics),可缩放矢量图,它是浏览器支持的一种基于 XML 语法的图像格式。相对于 Canvas2D 这种指令式的绘图系统来讲,SVG 是一种声明式的绘图系统,它的使用方式和普通的 DOM 元素非常像,所以使用起来比较简单。下面我们通过绘制和上面相同的内容来看看 SVG 的使用方法.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <svg
  xmlns="http://www.w3.org/2000/svg"
  version="1.1"
  width="400"
  height="200"
  viewBox="0, 0, 400, 200"
>
  <rect
    height="95"
    width="95"
    x="5"
    y="5"
    stroke="yellow"
    stroke-width="10"
    fill="red"
  />
  <text
    fill="black"
    font-family="PingFangSC-Regular, sans-serif"
    font-size="25"
    x="150"
    y="100"
  >
    hello world
  </text>
</svg>
</body>
</html>

SVG VS Canvas2D

就这样,不知不觉,我们就用 SVG 和 Canvas2D 从 0 到 1 绘制了一个简单的条形图,而且效果几乎一模一样。那么,它们分别有什么特点,以及分别适合什么样的绘制场景呢?

SVG 的优点是方便交互,因为它也有 DOM 结构,可以方便地监听事件。但是性能方面却有所影响:如果我们要绘制的图形非常复杂,这些元素节点的数量就会非常多。而节点数量多,就会大大增加 DOM 树渲染和重绘所需要的时间。

相比来说,Canvas 交互实现就不太容易,因为对每个图形的拾取(判断鼠标点位置在哪个图形上)需要开发者自己实现(很多渲染引擎会解决这个问题,我们后面会看到),但是它的绘制性能却相对较优。

所以当数据量不大且侧重交互的情况,用 SVG 比较合适;当数据量较大的时候用 Canvas 比较合适。

posted @ 2022-07-08 17:01  自在一方  阅读(333)  评论(0编辑  收藏  举报