Airglass,从碰撞的火花中,孕育一个种子,选对语言像选了对的舞台;配置一套构建环境像DNA按预定规则构建出各种蛋白质;不断完善的类继承关系像千丝万缕错综复杂的神经网络,诞生前的痛;添加事件监听器,像婴儿睁开了眼,接收来自这个世界的善意祝福;订阅事件,像身体各器官各细胞沟通协作。他登上了台。
继承关系
我将Airglass中凡是支持事件的类统一都去继承Event类。Element表示一类抽象元素,目前仅有Shape类继承了它。和Three相似的地方是,Airglass也定义了渲染器类和场景类。
最佳实践的前奏
到目前位置,Airglass已经具备完成最简单的交互操作的能力。我就拿Airglass中内置的几个基本形状给接下来一系列最佳实践的Demo项目们做一个最最简单的引子。这个引子完成后的交互方式如下图所示:
- 点击Glass空白区域,场景凭空新增一枚圆角矩形;
- 每一个圆角矩形都可以自由拖拽。
无论使用Airglass做何种最佳实践,我在下面列出的初始化用途的代码片段都会不可避免的出现在任何Airglass项目中。就让我用上面提到的引子来介绍如何开始书写一个最佳实践。第一步,创建canvas标签并创建上下文。我还没打算让Airglass管理canvas。
<canvas id="canvas"></canvas>
let ctx = document.querySelector('#canvas').getContext('2d');
第二步,创建一个场景类Scene的实例。场景用来收集所有元素。向场景中加入元素。
let scene = new airglass.Scene();
scene.add(new airglass.Module({
x: 110,
y: 110,
rx: 6,
ry: 6,
lineWidth: 2,
width: 80,
height: 80,
fillStyle: 'hsla(0, 0%, 100%, .5)',
strokeStyle: '#fff',
}), new airglass.Module({
x: 110,
y: 110,
rx: 6,
ry: 6,
lineWidth: 2,
width: 80,
height: 80,
fillStyle: 'hsla(0, 0%, 100%, .5)',
strokeStyle: '#fff',
}));
第三步,创建一个渲染器Renderer的实例。渲染器维护场景和canvas的上下文。随时执行渲染,渲染器会将场景中的全部物体渲染到Glass上。
let renderer = new airglass.Renderer( ctx, scene );
renderer.render();
渲染器都继承了Glass类。所有继承了Glass的渲染器既可以订阅其他渲染器,同样也可以订阅在自己的Glass上发生的事件。像下面这样渲染器订阅自己的情况是很常见的,我鼓励这样做。
renderer.subscribe(renderer, actor => {});
订阅了事件,为了释放资源也可以退订事件。我也给Glass类增加了unSubscribe方法,与subscribe相对,用来退订事件。如果需要退订事件,那么在订阅事件时就不能使用匿名函数了:
function rendererSubscriber( actor ) {}
renderer.subscribe(renderer, rendererSubscriber);
renderer.unSubscribe(renderer, rendererSubscriber);
我在实现上并没有修改开发者传入的订阅事件处理函数的This指向。一是因为所有希望This指向的对象都在这里了;二是我不应该过度控制狂。就像鼠标选中压在下方元素后,该元素是否跳到所有元素的顶部这件事,我一开始想当然的做了决定,后来觉得开发者可以自由决定这一切。
进化
接下来我将使用Airglass制作各式各样的Demo。让Airglass不断进化。