介绍
对于zrender是什么,官方介绍的已经很清楚了。
ZRender 是二维绘图引擎,它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器。
基本用法
- zrender初始化:使用zrender.init(dom, opt)初始化zrender实例
const zr = zrender.init(document.getElementById('container'));
- 实例化绘制的图形对象(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],
})
- 将图形渲染到画布上。
// 第一种方法:直接添加到画布上
zr.add(rect);
// 第二种方法:通过将同一组的图形元素添加到一个容器内,将容器添加到画布上,这样有利于图形的管理
const zrTipGroup = new zrender.Group();
zrTipGroup.add(rect);
zr.add(zrTipGroup);
简单实现柱状图
- 引入zrender,可以直接到www.bootcdn.cn/找到免费的CDN链接
<script src="https://cdn.jsdelivr.net/npm/zrender@4.3.0/dist/zrender.js"></script>
- 在页面中加入一个div,并初始化zrender实例
<body>
<div id="bar" style="width: 1000px; height: 400px"></div>
<script>
// 初始化zrender实例
const zr = zrender.init(document.getElementById('bar'));
</script>
</body>
- 绘制柱状图
// 创建图形元素
const bar = new zrender.Rect({
shape: {
cx: 0,
cy: 0,
width: 20,
height: 0,
},
style: {
fill: 'red',
},
position: [100, 100],
})
- 加入动画,使用animateTo方法实现动画,图形元素的高从0动画到90,这里还需要注意坐标的设置,坐标表示的是图形元素左上角在页面中的位置,在图形高度改变之后,对于的Y轴坐标也应该改变。
bar.animateTo({
shape:{
cx: 0,
cy: 0,
width: 20,
height: 90,
},
position: [100,10]
})
- 将图形渲染到页面上
zr.add(bar);
这样就实现了一个柱状图的显示效果,可以根据数值来设置柱状图对于的值。
最终效果:
zrender的动画原理
目前zrender5不支持VML渲染方式,只支持canvas和SVG的渲染方式,我这里简单描述一下canvas的动画原理:清屏-更新-渲染。
解释:在canvas绘制内容之后,canvas就将内容像素化了,canvas没有能力再次去获取这个元素并且去修改他,所以做动画需要再次重绘。
动画的本质就是连成连贯动作的一帧帧静态图组成的,MDN上有画一帧的步骤:
你可以通过以下的步骤来画出一帧:
- 清空 canvas 除非接下来要画的内容会完全充满 canvas(例如背景图),否则你需要清空所有。最简单的做法就是用
clearRect方法。- 保存 canvas 状态 如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。
- 绘制动画图形(animated shapes) 这一步才是重绘动画帧。
- 恢复 canvas 状态 如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。
在canvas画布上绘制内容需要在脚本执行结束之后才能看到效果,所以不能通过for循环去遍历实现动画,以下是zrender中实现动画的关键方法:
import env from '../core/env';
type RequestAnimationFrameType = typeof window.requestAnimationFrame
let 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;
\