今天是想看看使用zrender框架如何去,画一个圆,再加“circle”的文字在圆心。

然后开始代码:

如何部署代码,让zrender跑起来这边就不说了,官方例子就有写,地址是:https://github.com/ecomfe/zrender

准备工作如下:

dom中新建一个容器用于绘图:

然后直接写代码就可以了。

调用zrender的init接口初始化

// zrender_demo.html
var zr = zrender.init(document.getElementById('main'));

进入init方法,发现做2件事情:A、初始化ZRender;B、将其存入ZRender实例map索引

/**
* 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;
};

其中guid()是zrender统一的ID生成机制,通过esl加载,然后按需调用:

// zrender.js
var guid = require('./tool/guid');
guid(); // tool/guid.js
/**
* zrender: 生成唯一id
*
* @author errorrik (errorrik@gmail.com)
*/ define(
function() {
var idStart = 0x0907; return function () {
return 'zrender__' + (idStart++);
};
}
);

进入ZRender接口类,这边体现官网提到的“MVC核心封装实现图形仓库、视图渲染和交互控制”

  • Stroage(M) : shape数据CURD管理

  • Painter(V) : canvas元素生命周期管理,视图渲染,绘画,更新控制

  • Handler(C) : 事件交互处理,实现完整dom事件模拟封装

/**
* 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、Painter、Handler、animation的初始化暂时不细究跳过

好习惯是每次绘图前,都清空画布

// zrender_demo.html
zr.clear();

zrender执行清空时,清空storage后,再执行painter的clear()方法

// zrender.js
/**
* 清除当前ZRender下所有类图的数据和显示,clear后MVC和已绑定事件均还存在在,ZRender可用
*/
ZRender.prototype.clear = function () {
this.storage.del();
this.painter.clear();
return this;
};

同样暂不细究storage、painter的清除机制

接下来开始绘图,添加一个圆形

// zrender_demo.html
var color = require('zrender/tool/color');
var colorIdx = 0;
var width = Math.ceil(zr.getWidth()); // 视图宽度
var height = Math.ceil(zr.getHeight()); // 视图高度

F11查看getWidth(),调用painter的方法。getHeight类似实现

// zrender.js
/**
* 获取视图宽度
*/
ZRender.prototype.getWidth = function() {
return this.painter.getWidth();
};
// zrender_demo.html
var circle = new CircleShape({
style : {
x : 100,
y : 100,
r : 50,
brushType : 'both',
color : 'rgba(220, 20, 60, 0.8)', // rgba supported
strokeColor : color.getColor(colorIdx++), // getColor from default palette
lineWidth : 5,
text :'circle',
textPosition :'inside'
},
hoverable : true, // default true
draggable : true, // default false
clickable : true, // default false // 可自带任何有效自定义属性
_name : 'Hello~',
onclick: function(params){
alert(params.target._name);
}, // 响应事件并动态修改图形元素
onmousewheel: function(params){
var eventTool = require('zrender/tool/event');
var delta = eventTool.getDelta(params.event);
var r = params.target.style.r;
r += (delta > 0 ? 1 : -1) * 10;
if (r < 10) {
r = 10;
};
zr.modShape(params.target.id, {style: {r: r}})
zr.refresh();
eventTool.stop(params.event);
}
});

初始化圆Circle,直接调用基类

// shape/circle.js
function Circle(options) {
Base.call(this, options);
}

base中先对各属性进行默认值初始化,而后使用传入值覆盖

// shape/base.js
function Base( options ) {
this.id = options.id || guid();
this.zlevel = 0;
this.draggable = false;
this.clickable = false;
this.hoverable = true;
this.position = [0, 0];
this.rotation = [0, 0, 0];
this.scale = [1, 1, 0, 0]; for ( var key in options ) {
this[ key ] = options[ key ];
} this.style = this.style || {};
}

往storage中添加图形形状

// zrender_demo.html
zr.addShape(circle);
// zrender.js
/**
* 添加图形形状
*
* @param {Object} shape 形状对象,可用属性全集,详见各shape
*/
ZRender.prototype.addShape = function (shape) {
this.storage.add(shape);
return this;
};

执行绘图

// zrender_demo.html
zr.render();

zrender直接调用painter接口渲染

// zrender.js
/**
* 渲染
*
* @param {Function} callback 渲染结束后回调函数
* todo:增加缓动函数
*/
ZRender.prototype.render = function (callback) {
this.painter.render(callback);
return this;
};

Storage、 Painter、handler等未完待续。

zrender源码分析--初探如何画一个圆的更多相关文章

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

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

  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. ZRender源码分析2:Storage(Model层)

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

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

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

  6. Netty 核心组件 Pipeline 源码分析(二)一个请求的 pipeline 之旅

    目录大纲: 前言 针对 Netty 例子源码做了哪些修改? 看 pipeline 是如何将数据送到自定义 handler 的 看 pipeline 是如何将数据从自定义 handler 送出的 总结 ...

  7. zrender源码分析1:总体结构

    开始 zrender(Zlevel Render) 是一个轻量级的Canvas类库,这里是GitHub的网址 点我, 类似的类库有Kinetic.JS.EaselJS. 但貌似都没有zrender好用 ...

  8. zrender源码分析2--初始化Storage

    接上次分析到初始化ZRender的源码,这次关注内容仓库Storage的初始化 入口1:new Storage(); // zrender.js /** * ZRender接口类,对外可用的所有接口都 ...

  9. ZRender源码分析6:Shape对象详解之路径

    开始 说到这里,就不得不提SVG的路径操作了,因为ZRender完全的模拟了SVG原生的path元素的用法,很是强大. 关于SVG的Path,请看这里: Path (英文版) 或者 [MDN]SVG教 ...

随机推荐

  1. python学习 (三十五) logging

    1  demo import logging # log level: # DEBUG # INFO # Warning # Error # CRITICAL logging.basicConfig( ...

  2. 分析java类的初始化契机

    分析java类的静态成员变量初始化先于非静态成员变量   依上图中当class字节码文件被jvm虚拟机加载到内存中依次经过 连接 验证:对字节码进行验证 准备:给静态变量分配内存并赋予变量类型各自的默 ...

  3. Android:解决重复打开界面问题

    点击界面A按钮,打开界面B,由于startActivity操作是异步执行的,假如在短时间内快速点击按钮,可能会导致打开多个B界面,这个时候可以重写Activity的startActivity事件. p ...

  4. OD 实验(八) - 对一个程序的逆向

    程序: 运行 弹出 NAG 窗口,提示要花 20 美元注册 然后会进入主窗口 提示剩余 5 天的使用时间 点击,菜单栏 -> Help -> About 显示未注册版本 逆向: 用 OD ...

  5. SSD固态盘应用于Ceph集群的四种典型使用场景

    在虚拟化及云计算技术大规模应用于企业数据中心的科技潮流中,存储性能无疑是企业核心应用是否虚拟化.云化的关键指标之一.传统的做法是升级存储设备,但这没解决根本问题,性能和容量不能兼顾,并且解决不好设备利 ...

  6. django第一课大概了解

    项目目录介绍: -------- manage.py : Django项目里面的工具,通过它可以调用django shell和数据库等. mysite/ 主要是项目配置的信息,通常一次生成后不需要其他 ...

  7. 好记性不如烂笔头-Mysql查找如何判断字段是否包含某个字符串

    好记性不如烂笔头-Mysql查找如何判断字段是否包含某个字符串 利用mysql 字符串函数 find_in_set(); SELECT * FROM users WHERE find_in_set(' ...

  8. OpenLayers 3 之 地图视图(View)

    OpenLayers 3 之 地图视图(View) 初始化一幅地图,必备的三要素之一视图(view),这个对象主要是控制地图与人的交互,如进行缩放,调节分辨率.地图的旋转等控制.也就是说每个 map对 ...

  9. Java后端发送email实现

    依赖的jar包 <dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail& ...

  10. JSP页面中的时间显示问题

    在JSP页面中往往要将时间显示为指定格式的,如果传入的是Date类型很好解决 <fmt:formatDate value="${orderTime}" pattern=&qu ...