开始

zrender(Zlevel Render) 是一个轻量级的Canvas类库,这里是GitHub的网址 点我, 类似的类库有Kinetic.JS、EaselJS。 但貌似都没有zrender好用(可能是更加符合国人的习惯),强大的图表工具echarts就是在zrender基础上建立, 用zrender和echarts做了两个关于canvas的两个可视化项目之后,忍不住看了下zrender的项目代码(也有需要修改源代码的缘故), 但是翻开之后,代码的结构比较清晰,注释也都是中文,比较容易读懂。最大的感想就是,沒有像jQuery之类的对于代码极(bian)度(tai)的精简追求,各种意图一看便知。 如果对于zrender的api不熟悉,请移步github上,这里只对源码进行了一些详(qian)细(xian)的分析。

总体结构

关于总体结构,最贴切的描述恐怕也没这一张图来的爽: 从github将项目clone下来之后,打开src/zrender.js之后,有如下发现:

var _instances = {};    //ZRender实例map索引

var zrender = {};
zrender.version = '2.0.0'; /**
* zrender初始化
* 不让外部直接new ZRender实例,为啥?
* 不为啥,提供全局可控同时减少全局污染和降低命名冲突的风险!
*
* @param {HTMLElement} dom dom对象,不帮你做document.getElementById了
* @param {Object=} params 个性化参数,如自定义shape集合,带进来就好
*
* @return {ZRender} ZRender实例
*/
zrender.init = function(dom, params) {
var zi = new ZRender(guid(), dom, params || {});
_instances[zi.id] = zi;
return zi;
};

我想这里已经很明显,用zrender.init(dom)初始化的时候,直接new一个内部的ZRender对象进行返回,原因我想作者已经写的很明白了(提供全局可控同时减少全局污染和降低命名冲突的风险!) 总比每次new ZRender()好多了,最起码看起来是这样,并且把每个实例就行保存,便于维护。 至于周围的其他的三个方法,dispose,getInstance,delInstance 就没什么可说的了,不过在项目中,也怎么用得上。

/**
* zrender实例销毁,记在_instances里的索引也会删除了
* 管生就得管死,可以通过zrender.dispose(zi)销毁指定ZRender实例
* 当然也可以直接zi.dispose()自己销毁
*
* @param {ZRender=} zi ZRender对象,不传则销毁全部
*/
zrender.dispose = function (zi) {
if (zi) {
zi.dispose();
}
else {
for (var key in _instances) {
_instances[key].dispose();
}
_instances = {};
} return zrender;
}; /**
* 获取zrender实例
*
* @param {string} id ZRender对象索引
*/
zrender.getInstance = function (id) {
return _instances[id];
}; /**
* 删除zrender实例,ZRender实例dispose时会调用,
* 删除后getInstance则返回undefined
* ps: 仅是删除,删除的实例不代表已经dispose了~~
* 这是一个摆脱全局zrender.dispose()自动销毁的后门,
* take care of yourself~
*
* @param {string} id ZRender对象索引
*/
zrender.delInstance = function (id) {
delete _instances[id];
return zrender;
};

接下来就是核心的ZRender构造函数,这里可以很清晰的看到M(Storage)V(Painter)C(Handler)的结构.

/**
* ZRender接口类,对外可用的所有接口都在这里!!
* storage(M)、painter(V)、handler(C)为内部私有类,外部接口不可见
* 非get接口统一返回支持链式调用~
*
* @param {string} id 唯一标识
* @param {HTMLElement} dom dom对象,不帮你做document.getElementById
*
* @return {ZRender} ZRender实例
*/
function ZRender(id, dom) {
this.id = id;
this.env = require('./tool/env'); this.storage = new Storage();
this.painter = new Painter(dom, this.storage);
this.handler = new Handler(dom, this.storage, this.painter); // 动画控制
this.animatingShapes = [];
this.animation = new Animation({
stage : {
update : getAnimationUpdater(this)
}
});
this.animation.start();
}
  • Storage只是JS对象级别的对于Shape图形的增(add/addHover)删(del,delHover)改(mod)查(get/iterShape/getMaxZlevel等),更像一个数据结构的东西
  • Painter负责真正的绘图操作,这里是比较繁重的部分
    • 1.负责canvas及其周边DOM元素的创建与处理
    • 2.负责调用各个Shape(预定义好的)进行绘制
    • 3.提供基本的操作方法,渲染(render)、刷新(refresh)、尺寸变化(resize)、擦除(clear)等
  • Handler负责事件处理,解决基础的浏览器兼容问题、进行事件的注册与转发、拖动

至于附加在ZRender的prototype的其他方法,除了关于动画部分的,其他的都是调用的Storage、Painter、Handler,这里就不再赘述了。

结尾

能力有限,尽力而为,接下来,再详尽分析各个小模块吧。 大家也可以观摩经过我加工过的更加详细注释的代码 通往我的GitHub

zrender源码分析1:总体结构的更多相关文章

  1. ZRender源码分析2:Storage(Model层)

    回顾 上一篇请移步:zrender源码分析1:总体结构 本篇进行ZRender的MVC结构中的M进行分析 总体理解 上篇说到,Storage负责MVC层中的Model,也就是模型,对于zrender来 ...

  2. ZRender源码分析4:Painter(View层)-中

    回顾 上一篇说到:ZRender源码分析3:Painter(View层)-上,接上篇,开始Shape对象 总体理解 先回到上次的Painter的render方法 /** * 首次绘图,创建各种dom和 ...

  3. ZRender源码分析3:Painter(View层)-上

    回顾 上一篇说到:ZRender源码分析2:Storage(Model层),这次咱看来看看Painter-View层 总体理解 Painter这个类主要负责MVC中的V(View)层,负责将Stora ...

  4. MySQL源码分析以及目录结构 2

    原文地址:MySQL源码分析以及目录结构作者:jacky民工 主要模块及数据流经过多年的发展,mysql的主要模块已经稳定,基本不会有大的修改.本文将对MySQL的整体架构及重要目录进行讲述. 源码结 ...

  5. MySQL源码分析以及目录结构

    原文地址:MySQL源码分析以及目录结构作者:jacky民工 主要模块及数据流经过多年的发展,mysql的主要模块已经稳定,基本不会有大的修改.本文将对MySQL的整体架构及重要目录进行讲述. 源码结 ...

  6. ZRender源码分析5:Shape绘图详解

    回顾 上一篇说到:ZRender源码分析4:Painter(View层)-中,这次,来补充一下具体的shape 关于热区的边框 以圆形为例: document.addEventListener('DO ...

  7. ffplay源码分析2-数据结构

    ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg提供的解码器和SDL库进行视频播放.本文基于FFmpeg工程4.1版本进行分析,其中ffplay源码清单如下: https://gith ...

  8. zrender源码分析3--初始化Painter绘图模块

    接上次分析到初始化ZRender的源码,这次关注绘图模块Painter的初始化 入口1:new Painter(dom, this.storage); // zrender.js /** * ZRen ...

  9. Springboot源码分析之项目结构

    Springboot源码分析之项目结构 摘要: 无论是从IDEA还是其他的SDS开发工具亦或是https://start.spring.io/ 进行解压,我们都会得到同样的一个pom.xml文件 4. ...

随机推荐

  1. ThinkPHP框架搭建及常见问题(Apache或MySQL无法启动)----简单的初体验

    有一定基础的人勿进,这篇讲的只是零基础入门,都是我刚接触以及我所了解到的人刚开始有疑惑的地方,具体框架介绍会在后面的博客中介绍 这一篇只是为了一个简单的页面显示而介绍的方法,不涉及代码,开发环境,所以 ...

  2. GridView事件DataBinding,DataBound,RowCreated,RowDataBound区别及执行顺序分析

    严格的说,DataBinding,DataBound并不是GridView特有的事件,其他的控件诸如ListBox等也有DataBinding,DataBound事件. DataBinding事件MS ...

  3. tomcat中的URL参数为中文,servlet接收后显示乱码

    URL中参数的值为中文时,servlet接收后显示为乱码,如下图: 这时候需要修改tomcat的中的server.xml文件.该文件路径为 tomcat安装目录下的conf文件夹.   为修改前的se ...

  4. 从汇编看c++内联函数评估求值

    在c++中,一个inline函数实体,在整个class 声明未被完全看到之前,是不会被评估求值的,也就是说,对于类里面内联的成员函数本身的分析,要等到class的声明完全结束之后才开始.下面试c++源 ...

  5. win7使用右键导致死机、假死、explorer无法响应的解决方法

    右键引起explorer无法响应,奔溃,主要是由于COMCTL32.DLL和COMCTL21.OCX文件引起的 描述:comctl32.dll是Windows应用程序公用GUI图形用户界面模块.报告提 ...

  6. MySQL实用基础笔记

    /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限验证登录MySQL */ mysq ...

  7. 如何处理JS与smarty标签的冲突

    smarty的默认标记符是大括号:{}, 假如我们页面上有JS且定义了函数或者对象,或者有CSS定义了样式,就会出现大括号, smary引擎就会把这些大括号当作smarty语法来解释, 很明显,这些C ...

  8. Leetcode算法刷题:第112题 Path Sum

    Path Sum 题目 给予一个二叉树,和一个值su,寻找是否有一个从根节点到叶节点的和为su,有则返回True,没有为False.比如: 5 / \ 4 8 / / \ 11 13 4 / \ \ ...

  9. 定制样式插入到ueditor

    AngularJs定制样式插入到ueditor中的问题总结 总结一下自己给编辑器定制样式的过程中所遇到的问题,主要是编辑器的二次开发接口,以及用angular定制样式,问题不少,终于在**的帮助下,完 ...

  10. Vector, ArrayList, Array

    JAVA新手在使用JAVA的时候大概都会遇到这个问题: JAVA中的Array, ArrayList, Vector, List, LinkedList有什么样的区别?尤其是Vector, Array ...