目录
背景
当我们开发一个canvas应用的时候,出于效率的考量,免不了要选择一个渲染引擎(比如PixiJS)或者更强大一点的游戏引擎(比如Cocos Creator、Layabox)。
渲染引擎通常会有Sprite的概念,一个完整的界面会由很多的Sprite组成,如果编写复杂一点的界面,代码里面会充斥创建精灵、设置精灵位置和样式的“重复代码”,最终我们得到了极致的渲染性能却牺牲了代码的可读性。
游戏引擎通常会有配套的IDE,界面通过拖拽即可生成,最终导出场景配置文件,这大大方便了UI开发,但是游戏引擎一般都很庞大,有时候我们仅仅想开发个好友排行榜。
基于以上分析,如果有一款渲染引擎,既能用配置文件的方式来表达界面,又可以做到轻量级,将会大大满足我们开发轻量级canvas应用的场景。
本文会详细介绍开发一款可配置化轻量级渲染引擎
需要哪些事情,代码开源至Github:https://github.com/wechat-miniprogram/minigame-canvas-engine。
配置化分析
我们首先期望页面可配置化,来参考下Cocos Creator的实现:对于一个场景,在IDE里面一顿操作,最后场景配置文件大致长下面的样子:
// 此处省略n个节点
{
"__type__": "cc.Scene",
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_parent": null,
"_children": [
{
"__id__": 2
}
],
},
在一个JSON配置文件里面,同时包含了节点的层级结构和样式,引擎拿到配置文件后递归生成节点树然后渲染即可。PixiJS虽然只是个渲染引擎,但同样可以和cocos2d一样做一个IDE去拖拽生成UI,然后写一个解析器,声称自己是PixiJS Creator😬。
这个方案很好,但缺点是每个引擎有一套自己的配置规则,没法做到通用化,而且在没有IDE的情况下,手写配置文件也会显得反人类,我们还需要更加通用一点的配置。
寻找更优方案
游戏引擎的配置方案如果要用起来主要有两个问题:
- 手写可读性差,特别是对于层级深的节点树;
- 样式和节点树没有分离,配置文件冗余;
- 配置不通用;
对于高可读性和样式分离,我们惊讶的发现,这不就是Web开发的套路么,编写HTML、CSS丢给浏览器,界面就出来了,省时省力。
如此优秀的使用姿势,我们要寻求方案在canvas里面实现一次!
实现分析
结果预览
在逐步分析实现方案之前,我们先抛个最终实现,编写XML和样式,就可以得到结果:
let template = `
<view id="container">
<text id="testText" class="redText" value="hello canvas"> </text>
</view>
`;
let style = {
container: {
width: 200,
height: 100,
backgroundColor: '#ffffff',
justContent: 'center',
alignItems: 'center',
},
testText: {
color: '#ff0000',
width: 200,
height: 100,
lineHeight: 100,
fontSize: 30,
textAlign: 'center',
}
}
// 初始化渲染引擎
Layout.init(template, style);
// 执行真正的渲染
Layout.layout(canvasContext);
方案总览
既然要参考浏览器的实现,我们不妨先看看浏览器是怎么做的:
如上图所示,浏览器