zrender的动画及原理

1,784 阅读3分钟

介绍

对于zrender是什么,官方介绍的已经很清楚了。

ZRender 是二维绘图引擎,它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器。

基本用法

  1. zrender初始化:使用zrender.init(dom, opt)初始化zrender实例
const zr = zrender.init(document.getElementById('container'));
  1. 实例化绘制的图形对象(Rect、Line、Text、Path、Image),设置图形的各种属性(shape、style、position),修改图形元素可以使用zr.attr(key, value)的形式进行修改,否则不会触发重绘。
const rect = new zrender.Rect({
    shape: {
        x: 0,
        y: 0,
        height: 50,
        width: 50
    },
    style: {
        fill: 'yellow',
        lineWidth: 2
    },
    position: [xPoint, yPoint],
})
  1. 将图形渲染到画布上。
// 第一种方法:直接添加到画布上
zr.add(rect);
​
// 第二种方法:通过将同一组的图形元素添加到一个容器内,将容器添加到画布上,这样有利于图形的管理
const zrTipGroup = new zrender.Group();
zrTipGroup.add(rect);
zr.add(zrTipGroup);
​

简单实现柱状图

  1. 引入zrender,可以直接到www.bootcdn.cn/找到免费的CDN链接
<script src="https://cdn.jsdelivr.net/npm/zrender@4.3.0/dist/zrender.js"></script>
  1. 在页面中加入一个div,并初始化zrender实例
<body>
  <div id="bar" style="width: 1000px; height: 400px"></div>
  <script>
    // 初始化zrender实例
    const zr = zrender.init(document.getElementById('bar'));
    </script>
</body>
  1. 绘制柱状图
// 创建图形元素
    const bar = new zrender.Rect({
      shape: {
            cx: 0,
            cy: 0,
            width: 20,
            height: 0,
          },
          style: {
            fill: 'red',
          },
          position: [100, 100],
    })
  1. 加入动画,使用animateTo方法实现动画,图形元素的高从0动画到90,这里还需要注意坐标的设置,坐标表示的是图形元素左上角在页面中的位置,在图形高度改变之后,对于的Y轴坐标也应该改变。
bar.animateTo({
    shape:{
        cx: 0,
        cy: 0,
        width: 20,
        height: 90,   
    },
    position: [100,10]
})
  1. 将图形渲染到页面上
zr.add(bar);

这样就实现了一个柱状图的显示效果,可以根据数值来设置柱状图对于的值。

最终效果:

image-20220805173921100.png 代码地址:github.com/jiang-jt/zr…

zrender的动画原理

目前zrender5不支持VML渲染方式,只支持canvas和SVG的渲染方式,我这里简单描述一下canvas的动画原理:清屏-更新-渲染。

解释:在canvas绘制内容之后,canvas就将内容像素化了,canvas没有能力再次去获取这个元素并且去修改他,所以做动画需要再次重绘。

动画的本质就是连成连贯动作的一帧帧静态图组成的,MDN上有画一帧的步骤:

你可以通过以下的步骤来画出一帧:

  1. 清空 canvas 除非接下来要画的内容会完全充满 canvas(例如背景图),否则你需要清空所有。最简单的做法就是用 clearRect 方法。
  2. 保存 canvas 状态 如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。
  3. 绘制动画图形(animated shapes) 这一步才是重绘动画帧。
  4. 恢复 canvas 状态 如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。

在canvas画布上绘制内容需要在脚本执行结束之后才能看到效果,所以不能通过for循环去遍历实现动画,以下是zrender中实现动画的关键方法:

import env from '../core/env';
​
type RequestAnimationFrameType = typeof window.requestAnimationFramelet requestAnimationFrame: RequestAnimationFrameType;
​
// 兼容性处理,requestAnimationFrame有兼容性问题
requestAnimationFrame = (
    env.hasGlobalWindow
        && (
            (window.requestAnimationFrame && window.requestAnimationFrame.bind(window))
            // 
            || ((window as any).msRequestAnimationFrame && (window as any).msRequestAnimationFrame.bind(window))
            || (window as any).mozRequestAnimationFrame
            // @ts-ignore
            || window.webkitRequestAnimationFrame
        )
) || function (func: Parameters<RequestAnimationFrameType>[0]): number {
    return setTimeout(func, 16) as any;
};
​
export default requestAnimationFrame;

\