文档章节15

Documentation

Canvas 与 SVG 绘图方案选型

对比 Canvas 与 SVG 两种绘图方案的优缺点与适用场景,给出选型判断依据。

本页目录

绘制

方案优点缺点
纯 HTML简单,通过CSS即可绘制难以绘制复杂图形
Canvas1. 基于像素,内存占用恒定
2. 一张图只存在一个 HTML 元素
3. 大规模数据下,性能表现比svg 好
1. 事件交互基于整张画布,根据坐标计算出节点,编程方式繁琐
2. 不支持插入 HTML 元素,不支持 CSS 修改样式
3. 因为基于像素,大屏幕下渲染时间长
Svg1. 基于矢量,缩放不会失真
2. 基于 DOM,学习、编程成本低,事件交互都是基于 DOM,并且支持 CSS,使用方便
3. 适合静态图像,基于 Svg 也可以做转换
因为基于 DOM,当图的元素数量较多的时候,渲染性能比较低

流程图场景下,不需要渲染大量的节点,对动画的要求也不高,可以使用Svg + HTML 实现。

Canvas

Canvas 适合绘制图形密集且需要频繁更新的场景。

CanvasHTML5提供的绘图 api,允许在网页上进行即时的图形绘制。通常用于游戏开发、可视化、图像处理等场景。

  • 绘制一个canvas 图片
<body>
    <h1>绘制canvas</h1>
    <canvas id="canvas" width="200" height="200"></canvas>
    <button id="btn">绘制</button>
    <canvas id="canvas2" width="200" height="200"></canvas>
    <script>
        const canvas = document.getElementById("canvas");
        const ctx = canvas.getContext("2d");
        ctx.fillStyle = "dodgerblue";
        ctx.fillRect(10, 10, 180, 180);
        ctx.fillStyle = "black";
        ctx.font = "20px Arial";
        ctx.fillText("Fa-ce", 10, 30);        
        ctx.strokeStyle = "deeppink";

        const btn = document.getElementById("btn");
        btn.addEventListener("click", () => {
            const canvas2 = document.getElementById("canvas2");
            const ctx2 = canvas2.getContext("2d");
            ctx2.beginPath();
            ctx2.moveTo(75, 50);
            ctx2.lineTo(100, 75);
            ctx2.lineTo(100, 25);
            ctx2.fill();
        });
    </script>
</body>

Svg

SVG 适合静态图形和需要高精度的场景。

Svg是一种基于XML的矢量图格式(Scalable Vector Graphics)。在网页中通常通过嵌入XML或者使用js、css进行样式、动态操作。适用于矢量图标、地图、数据可视化场景。

  • 绘制Svg图片
<head>
    <style>
        svg {
            border: 1px solid #000;
        }
    </style>
    <script>
        function svgClick(msg) {
            debugger;
            // alert(msg);
            // 点击事件
        }
    </script>
</head>    
<body>
    <h1>绘制SVG</h1>
    <svg width="200" height="200" style="border: 1px solid #000">
        <rect
            width="100"
            height="100"
            style="fill: rgb(0, 0, 255); stroke-width: 10; stroke: rgb(0, 0, 0)"
            onclick="svgClick('First Svg')"
        />
    </svg>
    <svg width="200" height="200" style="border: 1px solid #000">
        <circle
            cx="100"
            cy="100"
            r="50"
            fill="red"
            onclick="svgClick('Second Svg')"
        />
    </svg>
</body>

CSS

CSS可以绘制简单的几何图形,如矩形、圆形、多边形。在样式控制、动画方面有独特的优势

<style>
    .circle {
        width: 100px;
        height: 100px;
        background-color: red;
        border-radius: 50%;
    }
    .rect {
        width: 100px;
        height: 100px;
        background-color: blue;
    }
    .ellipse {
        width: 100px;
        height: 50px;
        background-color: green;
        border-radius: 50%;
    }
    .triangle {
        width: 0;
        height: 0;
        border-left: 50px solid transparent;
        border-right: 50px solid transparent;
        border-bottom: 100px solid red;
    }
    .polygon {
        width: 100px;
        height: 100px;
        background-color: yellow;
        clip-path: polygon(0% 0%, 50% 0%, 50% 80%, 80% 100%, 0% 100%);
    }
</style>

<body>
    <h1>CSS</h1>
    <!-- 圆形 -->
    <div class="circle"></div>
    <!-- 矩形 -->
    <div class="rect"></div>
    <!-- 椭圆 -->
    <div class="ellipse"></div>
    <!-- 三角形 -->
    <div class="triangle"></div>
    <!-- 多边形 -->
    <div class="polygon"></div>
</body>

框架

GoJS

  • 不开源
  • 模型分离,双向绑定。Model描述数据模型,Diagram描述 UI 。
    数据/视图的更新引入了事务性机制,可以原子化提交,按事务回滚/撤销。
  • 可以局部更新数据