在上篇博客中,我们完成了对canvasLayer.js的分析,这篇我们主要对canvas文件夹下的另一篇js文件进行学习。
该文件为CanvasPainter.js,该文件是一个基于w3c canvas接口的canvasPainter类。在该类中,定义了构造函数、refresh()函数、addHover()函数、removeHover()函数、clearHover()函数、refreshHover()函数、_paintList()函数、_compositeManually()函数、_doPaintList()函数以及一些get函数等函数,这次我们主要围绕着这几个函数进行学习研究。
对于该canvasPainter类,他的构造函数无疑是最重要的一个方法。再他的构造函数中,传入了三个参数,分别是host(类型:HTMLDomElement|Canvas|Context)、storage(类型:qrenderer.core.Storage)、options(类型:对象Object)。再构造函数中,分别对对象中的属性进行赋值操作
this.type = 'canvas';
this.dpr = this.options.devicePixelRatio || devicePixelRatio;
this.host = host;
if (this.host.style) {
this.host.style['-webkit-tap-highlight-color'] = 'transparent';
this.host.style['-webkit-user-select'] = this.host.style['user-select'] = this.host.style['-webkit-touch-callout'] = 'none';
host.innerHTML = '';
}
this._host = null;
this.storage = storage;
this._layerConfig = {};
this._needsManuallyCompositing = false;
this._hoverlayer = null;
this._hoverElements = [];
this._tmpRect = new BoundingRect();
this._viewRect = new BoundingRect();
this._singleCanvas = !this.host.nodeName || this.host.nodeName.toUpperCase() === 'CANVAS';
在对对象的一些属性进行初始化赋值的过程中,必要的时候需要进行一定的判断,如在进行this.host.style的赋值操作的过程中,需要进行判断,是否有style属性,然后在进行赋值操作。对于this._host属性,此属性可以是 HTMLDomElement ,比如 DIV 标签;也可以是 Canvas 实例;或者是 Context 实例,因为在某些运行环境中,不能获得 Canvas 实例的引用,只能获得 Context。在浏览器环境中,this._host 是 QuarkRenderer自己自动创建的 div 层,在其它环境中,this._host 等于 this.root。
而对于下面的代码操作,是用于兼容各种运行时环境,如浏览器、节点-画布和微信小程序。
在这里进行判断,从而分别给出其他开发环境中,对象的赋值操作。使用 || 的操作进行兼容其他模式。
如果只能指定一个给定的画布,设备来创建高 dpi(是单位,一般指每英寸的像素,相当于密度) 图像,则创建图层。let canvasContainer = this.createDomRoot(this._width, this._height); 该句是在host中创建一个新的div,同时 this._host = canvasContainer;指出现在情况下的_host不同于host,对其进行重新赋值操作。最后 this.host.appendChild(canvasContainer);将canvasContainer添加到host的子件中。
if (this._singleCanvas) {
this.dpr = this.options.devicePixelRatio || 1;
let width = this.host.width || this.options.width || 0;
let height = this.host.height || this.options.height || 0;
this.host.width = width * this.dpr;
this.host.height = height * this.dpr;
this._width = width;
this._height = height;
// Create layer if only one given canvas
// Device can be specified to create a high dpi image.
let mainLayer = new CanvasLayer(this.host, this._width, this._height, this.dpr);
mainLayer.__builtin__ = true;
mainLayer.initContext();
// FIXME: Use canvas width and height
// mainLayer.resize(width, height);
layers[CANVAS_QLEVEL] = mainLayer;
mainLayer.qlevel = CANVAS_QLEVEL;
// Not use common qlevel.
qlevelList.push(CANVAS_QLEVEL);
this._host = this.host; // Here, this._host equals this.host.
} else {
this._width = this._getSize(0);
this._height = this._getSize(1);
let canvasContainer = this.createDomRoot(this._width, this._height);
this._host = canvasContainer;
this.host.appendChild(canvasContainer);
}
至此,我们分析了该js中的构造函数部分,并对一些关键部分进行了深刻剖析,得到一些关于创建canvas实例的逻辑实现,并对实例中的一些属性有了相关的认识。下篇将会对其他的关键函数进行解析。