有句成语说:磨刀不误砍柴工。
本节介绍ZRender知识。
为什么选择ZRender
ZRender 是二维绘图引擎,它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器。
ZRender的优点:
简单
数据驱动
完整的事件封装
高效的分层刷新
丰富的图形选项
强大的动画支持
易于扩展
传送门:zrender官网
熟悉ZRender基本的api
ZRender图形
新建一个html文件,代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>熟悉 ZRender API </title> <style> html,body{ height:100%; width:100%; } body{ padding:0; margin:0; } #main{ width:100%; height:100%; } </style> </head> <body> <!-- 容器 --> <div id="main"></div> <!-- 引入zrender --> <script src="https://cdn.bootcss.com/zrender/4.0.7/zrender.min.js"></script> <script> //初始化一个实例 var zr = zrender.init(document.getElementById('main'),{ renderer:'canvas', //渲染方式 支持'canvas','svg','vml' devicePixelRatio:1, //画布大小与容器大小之比,仅当 renderer 为 'canvas' 时有效 width:'auto', //画布宽度 height:'auto' //画布高度 }); //这里练习代码 </script> </body> </html>
创建一个矩形
var rect=new zrender.Rect({ style:{ fill:'red', //填充颜色 stroke:'none' //描边颜色 }, shape:{ x:100, //x,y代表坐标 y:100, width:200, height:100, r:[3] //圆角 }, z:1 //层次,大的会覆盖小的 }); zr.add(rect);
创建了一个位置(左上角)在[100,100],长200宽100的背景颜色为红色的矩形,如下图:
还可以通过平移设置位置:
var rect=new zrender.Rect({ position:[100,100], //平移距离, style:{ fill:'red', stroke:'none' }, shape:{ x:0, y:0, width:200, height:100, r:[3] }, z:1 });
效果和上面一致,实际上矩形位置是属性 position 和 shape 属性(x,y)之和,但要注意的是,使用
rect.getBoundingRect() //获取元素的包围盒
得到的结果是不一样的,获取到的都是shape属性
如何更改矩形属性?
rect.attr({ style:{ fill:'yellow' }, shape:{ width:300, height:200 } })
使用attr方法,将矩形颜色更改为黄色,宽度更改300,高度更改为200,该方法触发重绘操作
如何给图形添加事件响应?
//点击事件 rect.on('click',function(e){ console.log('点击了矩形') }); //或者给zr添加事件绑定 zr.on('click',function(e){ //可以查看 e 里包含的属性,进行判断 console.log(e) });
ZRender支持的事件有: ‘click’、 ‘mousedown’、 ‘mouseup’、 ‘mousewheel’、 ‘dblclick’、 ‘contextmenu’。
给图形添加动画支持
animate函数
animate(path, loop):
path 对该对象的哪个元素执行动画
loop 是否循环
rect.animate('shape',true) .when(1000, {x:100}) .when(2000,{x:0}) .when(3000,{y:100}) .when(4000,{y:0}) .start();
效果如下:
animateTo 函数
animateTo(target, time, delay, easing, callback, forceAnimate):
target 设置动画的对象
time 动画
delay 动画延迟执行的时长
easing 缓动函数名称
callback 动画执行完成后的回调函数
forceAnimate 对于相同的属性,是否强制执行
rect.animateTo({ shape: { width: 500 }, style: { fill: 'blue' }, position:[10,10] }, 1000, 100, 'cubicOut', function () { console.log('done') }); 时长
将矩形宽度缓慢的增加至500,颜色改变为蓝色,如下图:
图形里的文字
//很多属性和css里的属性一致 rect.attr({ style:{ text:'图形文字', //文字 textFill:'#333', //文字颜色 fontSize:12, //文字大小 fontFamily:'', //字体 fontStyle:'normal', //字形 fontWeight:'normal', //加粗 textStroke:'yellow', //文字描边 textWidth:1, //字体线宽 textHeight:12, //字体高度 textLineWidth:1, //字体描边线宽 textLineHeight:14, //字体行高 textPosition:'inside', //字体位置 textPadding:[0,0,0,0], //文字内边距 transformText:true //字体跟随变换效果 } })
这里面要注意字体的大小,行高,内边距,文字位置等属性等,这些属性在后面会影响一个节点的大小。
图形变换
//假如 rect shape属性如下 ... shape:{ x:200, //x,y代表坐标 y:100, width:80, height:60, r:[3] //圆角 } ... //旋转 rect.animateTo({ rotation:Math.PI/3, //正值代表逆时针旋转,负值代表顺时针旋转 origin:[200,100] //设置变换中心 }) //放大,缩小 rect.animateTo({ scale:[1.5,1.5], //x,y轴方向放大至1.5倍 origin:[240,130] }) //平移 rect.animateTo({ position:[100,100] //x,y轴分别平移10 })
注意将style里的属性transformText设置为true,使得字体跟随变换效果,如下图:
ZRender还支持许多其他图形,例如:
//圆形 var circle=new zrender.Circle({ style:{ fill:'red' }, shape:{ cx:100, //圆心X坐标 cy:100, //圆心Y坐标 r:80 //半径 }, z:2 }); zr.add(circle); //圆弧 var arc=new zrender.Arc({ style:{ stroke:'none', fill:'red' }, shape:{ cx:300, cy:300, r:40, startAngle:0, //开始角度 endAngle:Math.PI/3 //结束角度 } }); zr.add(arc); //扇形 var sector=new zrender.Sector({ style:{ fill:'red' }, shape:{ cx:100, cy:100, r:80, //外半径 r0:60, //内半径 startAngle:0, //开始角度 endAngle:Math.PI/3, //结束角度 clockwise:true //顺时针 } }); zr.add(sector); //椭圆 var ellipse=new zrender.Ellipse({ style:{ fill:'red' }, shape:{ cx:100, cy:100, rx:160, //横向半径 ry:80 //纵向半径 } }) zr.add(ellipse); //心型 var heart =new zrender.Heart({ style:{ fill:'red' }, shape:{ cx:200, cy:200, width:100, height:100 } }); zr.add(heart); //多边形 var Polygon=new zrender.Polygon({ style:{ fill:'red' }, shape:{ points:[[100,100],[200,80],[300,160],[150,130]] //坐标集合 } }) zr.add(Polygon) //等等
组的概念
组。Group 是一个容器,可以插入子节点,Group 的变换也会被应用到子节点上
这是一个很重要的概念,后面思维导图实现的节点都是用[组]组合的。
关注组的几个重要的API:
//getBoundingRect() 获取元素包围盒 var g=new zrender.Group({ slient:true //组内子孙元素是否响应鼠标事件 }); var rect=new zrender.Rect({ style:{ fill:'red' }, shape:{ x:0, y:0, width:200, height:100 } }); var circle=new zrender.Circle({ style:{ fill:'red' }, shape:{ cx:200, cy:50, r:50 } }); g.add(rect); g.add(circle); zr.add(g); console.log(rect.getBoundingRect()); //返回{x: 0, y: 0, width: 200, height: 100} console.log(circle.getBoundingRect()); //返回 {x: 150, y: 0, width: 100, height: 100} console.log(g.getBoundingRect()); //返回{x: 0, y: 0, width: 250, height: 100} //遍历组内元素 g.eachChild(function(item){ console.log(item); }) //在组内删除元素 g.remove(circle) //指定删除 g.removeAll() //清空组内所有元素 //整体变换,如 g.attr({ position:[100,100] //x轴,y轴分别平移100 })
效果如下图:
线
//直线 var line =new zrender.Line({ style:{ stroke:'red', //线的颜色 lineWidth:1, //线宽 lineDash:[0] //虚线样式 }, style:{ x1:10, //起始点横坐标 y1:10, //起始点纵坐标 x2:100, //结束点横坐标 y2:100, //结束点横坐标 percent:1 } }); //多边形折线段 var polyline=new zrender.Polyline({ style:{ stroke:'red', //线的颜色 lineWidth:1, //线宽 lineDash:[0] }, shape:{ points:[[10,10],[100,100],[100,200]] //点集 } }) //贝塞尔曲线 var bezierCurve=new zrender.BezierCurve({ style:{ stroke:'red' }, shape:{ x1:10, //起始点横坐标 y1:10, //起始点纵坐标 x2:200, //结束点横坐标 y2:200, //结束点横坐标 cpx1:50, //控制点横坐标 cpy1:50 //控制点纵坐标 } });
文字
ZRender 对文字的支持很强大。
var text=new zrender.Text({ style:{ text:'这是一段文字'+'\n'+'换行' } }); //可以通过getBoundingRect()获取文字所占的空间 console.log(text.getBoundingRect()); //返回{x: 0, y: 0, width: 72, height: 24, lineHeight: 12} //特别注意的是rect必须设置宽高,才能获取到其所占的空间 //例如 var rect=new zrender.Rect({ style:{ text:'这是文字' }, shape:{ x:10, y:10 } }) console.log(rect.getBoundingRect()) //返回{x: 10, y: 10, width: 0, height: 0} //文字包围盒 var text=new zrender.Text({ style:{ text:'这是一段文字', textBackgroundColor:'red', //包围盒背景 textBorderColor:'#ccc', //包围盒描边颜色 textBorderWidth:1, //包围盒描边线宽 textPadding:[10,20,10,20] //文字内边距,同css Padding } });
效果图(没使用rect):
总结
Zrender的基本知识就介绍到这里,总之通过本节的介绍,我们要关注的知识点:
创建图形的方法
修改图形属性的方法(使用attr方法,触发重绘操作)
通过getBoundingRect()获取元素包围盒
组的概念
线段的概念
文字以及文字属性的设置,文字包围盒,如何换行
如何添加事件支持