今天是想看看使用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. node中express的中间件之methodOverride

    methodOverride中间件必须结合bodyParser中间件一起使用,为bodyParser中间件提供伪HTTP方法支持. index.html代码: <!DOCTYPE html> ...

  2. 浅谈PHP面向对象编程(八、多态)

    8.0  多态 在设计一个成员方法时,通常希望该方法具备一定的通用性.例如要实现一个动物叫的方法,由于每个动物的叫声是不同的,因此可以在方法中接收-个动物类型的参数的对象当传人猫类对象时就发出猫类的叫 ...

  3. php效率优化

    php效率优化 最近在公司一边自学一边写PHP程序,由于公司对程序的运行效率要求很高,而自己又是个新手,一开始就注意程序的效率很重要,这里就结合网上的一些资料,总结下php程序效率优化的一些策略:1. ...

  4. C# 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke [问题点数:40分

    注意:  this.DateTimeRun = true;            new Thread(jishi_kernel).Start(); 线程的启动,不能放在    public Form ...

  5. vertex shader(4)

    Swizzling and Masking 如果你使用输入.常量.临时寄存器作为源寄存器,你可以彼此独立地swizzle .x,.y,.z,.w值.如果你使用输出.临时寄存器作为目标寄存器,你可以把. ...

  6. 【311】Python 构建 ArcMap 标注表达式

    参考:构建标注表达式(官方帮助) 参考:计算字段示例(官方帮助) 说明:以上两者的方法略有不同,一个是通过字段表达式显示标注,一个通过字段计算新的字段,使用的工具方法也不同,前者通过 Layer.la ...

  7. PHP - 脚本退出(包括异常退出),执行指定代码

    之前做聊天室的时候有那么个需求就是当用户异常断线的时候就应该清除她的在线状态.因为当时对于flush不够了解,尝试了各种办法,好像都没办法在我们开发机上面执行相应的代码.后来知道是flush的原因.我 ...

  8. bps、bit、byte的区别

    bps是速度单位,bit是大小单位,byte也是大小单位1bps=1bit每秒, 8bit=1byte 1 Byte = 8    bits1 KB   = 1024 Bytes1 MB   = 10 ...

  9. 自动补齐flexselect+级联下拉框案例

    在开发web应用时,经常遇到类似省市区级联下拉框操作,即选中省份自动级联加载该省份所有的市,选中市自动级联加载该市所有的区:假设省市区的数据量很大,此时用户想选中某市,因而要从上往下查找,可能半天都找 ...

  10. Linux实战教学笔记32:企业级Memcached服务应用实践

    一, Memcached介绍 1.1 Memcached与常见同类软件对比 (1)Memcached是什么? Memcached是一个开源的,支持高性能,高并发的分布式内存缓存系统,由C语言编写,总共 ...