zrender源碼分析--初探如何畫一個圓


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

然后開始代碼:

如何部署代碼,讓zrender跑起來這邊就不說了,官方例子就有寫,地址是:https://github.com/ecomfe/zrender

准備工作如下:

dom中新建一個容器用於繪圖:

QQ截圖20140928151708

然后直接寫代碼就可以了。

調用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等未完待續。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM