Skip to content
花生PeA edited this page Feb 24, 2019 · 7 revisions

Short Night 支持扩展,扩展可能拿到所有组件的实例,并监听 Component 的生命周期。

其中 onApply 可以返回一个 Promise 来完成异步操作。

理想情况下,使用 Short Night 开发的 Timeline 应该在没有任何扩展的情况下依旧能够正常工作。

创建扩展

下边是一个最基本的扩展:

import { Extension} from 'short-night/extensions';

class NewExtension implements Partial<Extension> {
    constructor(public ext :ExtensionManager) {}
}

扩展内部可以通过this.ext拿到扩展管理器的实例(实际上是由构造时传入的),扩展管理器中包含全部的 Component 实例(不包括已销毁的)。

扩展内还可以实现下边的任意方法来监听所有组件的生命周期:

  • onConstruct
  • onApply
  • onDraw
  • onHide
  • onDestroy

扩展中还有一个可选type字段来指示扩展的类型。

使用一个扩展

你可以在任何时候使用一个扩展,只需要在扩展管理器中添加即可。如在组件内执行:

this.ext.extensions.push(
    new AnExtension(this.ext)
);

推荐将添加扩展的逻辑放在 Timeline Component 的构造函数当中。

扩展管理器

在组件和扩展构造时,一个扩展管理器对象会被传入。同一个 Timeline 的下的 Component 和扩展都应该使用相同的扩展管理器。

扩展管理器提供了一些非常有用的信息,其中最常用的是

  • components:所有 Component 的实例,不包含已销毁的
  • extensions:所有扩展。可以通过.extensions.push(...)来添加一个扩展

更多信息见 ExtensionManager

一般情况下,你无需扩展扩展管理器本身,通过添加一个扩展和增加.extraData可以完成大部分的功能。

禁用扩展

推荐在开发 Timeline 时禁用扩展,首先将所有 Component 开发完成,然后再应用扩展。

你可以构造扩展管理器时传入disableAll来禁用所有扩展,或者使用disableAllButDebug来禁用除 debug 相关外的所有扩展:

new ExtensionManager({ disableAllButDebug: true }),

或者在 Timeline 的构造函数中设置this.ext.disableAllButDebug= true;

某些写在 Component 内部还是剥离成扩展

大部分功能可以同时使用扩展的方式,或者写在 Component 内部的方式,两种方式均可以实现。这时候,如何判断代码应该放在扩展内还是 Component 内呢?

如果满足以下几点,是合适作为一个扩展来实现的:

  • 需要横向修改(非直接子节点)多个 Component 的内部状态(drawInfo、extraData 等)
  • 若放在 Component 内部,必须依赖于this.ext实现
  • Timeline 能够在脱离该扩展的情况下依旧正确运行

核心扩展

PositionCounter

该扩展会重新计算某些 Component 的定位属性,其存在的主意原因在于:AxisMilestone不应该占据轴线的长度

试想一下:

一根长度为 300px 的轴线上边有2个 AxisMilestone ,每个 AxisMilestone 的 height 是 50px。

此时,所有的 EventBody、EventAxis、AxisScale 在计算自身定位时都应该按照轴线长度为 200px 来计算。且EventBody、AxisScale 在遇到 AxisMilestone 顺延,而 EventAxis 若跨过 AxisMilestone 则需要增加额外的长度。

只有这样才能保证时间对齐的丝毫不差。

这就是 PositionCounter 做的。

IdGenerator

该扩展类型为Debug

为每个 Component 创建一个 id,格式是 Component 名 + 随机字符串,存放在组件内的.extraData.id

若处于 Debug 模式,在一个 Component apply()后还会创建同名的全局变量。

BoxElementGenerator

该扩展类型为DebugOnly,仅在 Debug 模式下会生效。

根据 Component 的.drawInfo.box来创建一个 DOM 节点插入Component 内的 .container,方便调试。

依赖于 IdGenerator。

BreakpointAnimation

在组件 apply() 时提供断点支持,在调试 Short Night 内部行为时,使用预先设置好的断点非常好用。

该扩展还能自动前进,可以完成“一步步展现 Short Night 的工作过程”的动画。

更多信息见调试工具#打断点

ConflictFixer

用于修复 Component 间的重叠,目前已支持:

  • EventAxis2EventAxis:通过调节 .drawInfo.offsetX 来修复 EventAxis 之间的冲突
  • EventBody2AxisMilestone:通过调节 eventBody.drawInfo.offset.x 来修复 EventBody 与 AxisMilestone 之间的冲突
  • EventBody2EventBodyFloater:通过调节 eventBody.drawInfo.offset 来修复 EventBody 之间的冲突
  • EventBody2EventBodyMover:通过调节 eventBody.drawInfo.float 来修复 EventBody 之间的冲突

暂不支持对此部分进行定制化。