Loading...
通常用户使用 G 绘图可以分成三步:
其中,场景图是独立于各种渲染器的抽象,因此在组件库、布局系统这类与实际渲染效果无关的应用中,并不需要直接与渲染器打交道,各个渲染器应该保证在各自环境下的一致渲染效果。在构建场景图,操作图中节点的语法上,我们提供了与 DOM API 一致的方法,同时提供类似 CSS 选择器的语法来查询图中节点,尽可能减少前端的学习成本。
在扩展性上,我们从场景图和渲染服务两个维度提供了插件机制。
场景图的插件关心每个节点的生命周期,选取其中的某些阶段扩展节点能力。
我们定义了统一的核心渲染层,它不关心具体渲染器的实现,暴露生命周期供扩展。以 WebGL 渲染器为例,它通过注册插件,为场景图中每一个节点扩展了 Material 等组件,得以适应 WebGL 渲染环境。
通过依赖注入使各个渲染器实现统一的上下文、渲染服务接口,核心层并不关心具体渲染器实现,因此可以在运行时动态替换不同渲染器。
我们在 G 的核心层定义了一套统一的渲染服务,该服务定义了如下生命周期。各个渲染器通过关联生命周期中的各个阶段,完成各自渲染环境下的渲染流程:
hooks = {// 渲染服务初始化,切换到新渲染器时也会调用init: new SyncHook<[]>(),// 处理待渲染对象prepareEntities: new AsyncSeriesWaterfallHook<[Entity[], DisplayObject]>(['entities', 'root']),// 渲染帧开始beginFrame: new AsyncSeriesHook<[Entity[]]>(['entities']),// 渲染中renderFrame: new AsyncSeriesHook<[Entity[]]>(['entities']),// 渲染帧结束endFrame: new AsyncSeriesHook<[Entity[]]>(['entities']),// 渲染服务销毁,切换到新渲染器后,旧渲染器调用destroy: new SyncHook<[]>(),};
其中核心层实现了一系列通用插件,它们与具体渲染环境无关:
MountDisplayObjectPlugin
mounted
生命周期DirtyCheckPlugin 实现脏矩形渲染
CullingPlugin 负责剔除,得到需要重绘的最小对象集合
visiblity
和视口包围盒剔除SortPlugin 负责对象排序
z-index
排序DirtyRectanglePlugin
context.save()
context.restore()