zrender源码分析--初探

先看下,本次例子做的效果

105230_IFJc_93398.png

然后开始代码:

调用init接口初始化

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

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

// zrender.js 
/**
 * 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 || {});// guid()生成zrender唯一id
 _instances[zi.id] = zi;
 return zi;
};

 

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

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

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

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

105303_mNqe_93398.png

// zrender.js
/**
 * 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();                    //shape数据CURD管理
 this.painter = new Painter(dom, this.storage);    //canvase元素生命周期管理,视图渲染,绘画,更新控制
 this.handler = new Handler(dom, this.storage, this.painter);//事件交互处理,实现完整dom事件模拟封装
 // 动画控制
 this.animatingShapes = [];
 this.animation = new Animation({
  stage : {
   update : getAnimationUpdater(this)
  }
 });
 this.animation.start();
}

 这边Storage、Painter、Handler的初始化暂时不细究跳过

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

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

转载于:https://my.oschina.net/haplone/blog/318458

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值