PIXI.js源码解析(1)——DisplayObject

Pixi.js是一个用JavaScript写的2D渲染引擎,可以用来在浏览器里做交互图形、动画和游戏等应用,主打支持硬件GPU渲染的WebGL API,如浏览器不支持WebGL,Pixi则会退用HTML5 Canvas来渲染。

接下来先来分析基础显示架构,其实很多渲染引擎都有类似的结构,如果学过as3的估计会感觉特别亲切。

显示架构

DisplayObject是所有可以被渲染在屏幕上的类的基类,DisplayObject继承了EventEmitter。
EventEmitter主要提供一个通用的事件的发送和接受功能,在网上有很多对这个类的解析,自己写一个也很轻松,将直接的函数调用解耦成事件的监听器和事件对象,具体的这里就不详细说了。


DisplayObject的主要属性有

transform
保存了该显示对象的坐标,缩放,旋转,内部使用了很多矩阵运算,所以效率很高,实际上as3也是使用一个transform来保存属性。而我们经常直接调用的x,y属性其实还是从transform里取的,在transform里可以看到,如图这里写图片描述
这里写图片描述
alpha
代表透明度

visible
是否可见

parent
父对象,pixi的显示架构类似一种树结构,每个对象由自己的父对象的引用,而且还有对所以子对象的引用(在container中)

worldAlpha
世界透明度,实际被渲染到屏幕上时的透明度,比如父容器的透明度为0.5,该对象的透明度为0.5,则worldAlpha,最后渲染时的透明度为0.5*0.5=0.25

_filters
所有滤镜对象,pixi支持许多滤镜对象,例如blur模糊滤镜,shadow投影滤镜。

_bounds
边界框,这也是一个非常重要的属性,代表了容纳该对象所需要的一个最小的rect,应该可以翻译为边界框,对象的width和height都是根据该对象得到,以后我们会专门介绍这个类。

_mask
遮罩对象

其他的一些属性估计看英文名就知道什么意思了,这边就不多说了。接下来介绍一下pixi里的广泛运用的一种优化策略。

在pixi.js源码里经常会出现xxxid的属性,例如
这里写图片描述
这里写图片描述

这边我们就拿bound举例子吧,计算bound是一个相当耗时的操作,需要递归遍历所有的子级,然后比较,找出极值点,然后找出四个这样的点,组成一个rect。那么一个物体的bound什么时候会改变呢,想一想就可以知道,添加子级,删除子级,改变子级位置时,父级的bound有可能会改变。
例如在container的addchild中
这里写图片描述
可以看到最后面有一句
this._boundsID++,我们前面已经说到,添加子级,删除子级,改变子级位置时,父级的bound有可能会改变,但是这边却没有立即重新计算bound,而只是递增了_boundsID,有经验的话,应该可以预测到最后在某个地方boundID会与lastboundID进行比较。那么bound到底在什么时候被重新计算呢?
找了一下源码,发现
这里写图片描述
只有真正需要bound,即调用GetBound时,bound才会比较boundID和lastboundID,如果不一样就重新计算bound。

可以想到,在使用这样一个渲染引擎中,使用一个for添加许多子对象到某容器中是一个相当常见的操作,如果每次addChild都重新计算bound,那估计效率就会很差。

而每次不直接改变bound,而是在可能改变时递增id,然后在对象真正被get的时候,使用id与lastID比较才被重新计算出来,其实是一种非常好的优化方法,一个属性只有他真正的需要的时候才会被计算出来,而不是每次该属性可能改变的时候都重新计算

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值