|
@@ -1,177 +0,0 @@
|
|
|
-
|
|
|
|
|
-# 核心建模
|
|
|
|
|
-
|
|
|
|
|
-Playground 底层会提供一套坐标系
|
|
|
|
|
-
|
|
|
|
|
-```ts
|
|
|
|
|
-interface Playground {
|
|
|
|
|
- node: HTMLDivElement // 画布挂载的dom节点
|
|
|
|
|
- scrollToView({
|
|
|
|
|
- entities?: Entity[] // 指定节点
|
|
|
|
|
- easing?: boolean // 开启缓动
|
|
|
|
|
- bounds?: Reactangle // 指定到特定的bbox位置
|
|
|
|
|
- }) // 让画布缓慢滚动到某个特定节点并居中
|
|
|
|
|
- toReactComponent() // 渲染为react 节点
|
|
|
|
|
- readonly: boolean // 只读模式
|
|
|
|
|
- config: PlaygroundConfigEntity // 包含 zoom,scroll 等画布数据
|
|
|
|
|
-}
|
|
|
|
|
-// hook 快速获取
|
|
|
|
|
-const playground = usePlayground()
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-## Layer
|
|
|
|
|
-
|
|
|
|
|
-:::warning P.S.
|
|
|
|
|
-- 渲染层在底层建立了一套自己的坐标系,基于这个坐标系实现模拟滚动、缩放等逻辑,在算viewport时候节点也需要转换到该坐标系上
|
|
|
|
|
-- 渲染按画布被拆分成多个层 (Layer),分层设计是基于ECS的数据切割思想,不同 Layer 只监听自己想要的数据,独立渲染不干扰,Layer 可以理解为ECS的 System,即最终Entity数据消费的地方
|
|
|
|
|
-- Layer 实现了类mobx的observer响应式动态依赖收集,数据更新会触发 autorun或render
|
|
|
|
|
-
|
|
|
|
|
-:::
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-- Layer 生命周期
|
|
|
|
|
-
|
|
|
|
|
-```ts
|
|
|
|
|
-interface Layer {
|
|
|
|
|
- /**
|
|
|
|
|
- * 初始化时候触发
|
|
|
|
|
- */
|
|
|
|
|
- onReady?(): void;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * playground 大小变化时候会触发
|
|
|
|
|
- */
|
|
|
|
|
- onResize?(size: PipelineDimension): void;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * playground focus 时候触发
|
|
|
|
|
- */
|
|
|
|
|
- onFocus?(): void;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * playground blur 时候触发
|
|
|
|
|
- */
|
|
|
|
|
- onBlur?(): void;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 监听缩放
|
|
|
|
|
- */
|
|
|
|
|
- onZoom?(scale: number): void;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 监听滚动
|
|
|
|
|
- */
|
|
|
|
|
- onScroll?(scroll: { scrollX: number; scrollY: number }): void;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * viewport 更新触发
|
|
|
|
|
- */
|
|
|
|
|
- onViewportChange?(): void;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * readonly 或 disable 状态变化
|
|
|
|
|
- * @param state
|
|
|
|
|
- */
|
|
|
|
|
- onReadonlyOrDisabledChange?(state: { disabled: boolean; readonly: boolean }): void;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 数据更新自动触发react render,如果不提供则不会调用react渲染
|
|
|
|
|
- */
|
|
|
|
|
- render?(): JSX.Element
|
|
|
|
|
- }
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-Layer的定位其实和 Unity 游戏引擎 提供的 [MonoBehaviour](https://docs.unity3d.com/ScriptReference/MonoBehaviour.html) 类似, Unity 游戏引擎的脚本扩展都是基于这个,可以认为是最核心的设计,底层也是基于 C# 提供的反射 (Reflection) 能力的依赖注入
|
|
|
|
|
-
|
|
|
|
|
-```C#
|
|
|
|
|
-using System.Collections;
|
|
|
|
|
-using System.Collections.Generic;
|
|
|
|
|
-using UnityEngine;
|
|
|
|
|
-public class MyMonoBehavior : MonoBehaviour
|
|
|
|
|
-{
|
|
|
|
|
- void Awake()
|
|
|
|
|
- {
|
|
|
|
|
- Debug.Log("Awake method is always called before application starts.");
|
|
|
|
|
- }
|
|
|
|
|
- void Start()
|
|
|
|
|
- {
|
|
|
|
|
- Debug.Log("Start method is always called after Awake().");
|
|
|
|
|
- }
|
|
|
|
|
- void Update()
|
|
|
|
|
- {
|
|
|
|
|
- Debug.Log("Update method is called in every frame.");
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-- Layer 的响应式更新
|
|
|
|
|
-
|
|
|
|
|
-```ts
|
|
|
|
|
-export class DemoLayer extends Layer {
|
|
|
|
|
- // 任意的inversify模块 的注入
|
|
|
|
|
- @inject(FlowDocument) document: FlowDocument
|
|
|
|
|
- // 监听单个Entity
|
|
|
|
|
- @observeEntity(SomeEntity) entity: SomeEntity
|
|
|
|
|
- // 监听多个Entity
|
|
|
|
|
- @observeEntities(SomeEntity) entities: SomeEntity[]
|
|
|
|
|
- // 监听 Entity的数据块(ECS - Component)变化
|
|
|
|
|
- @observeEntityDatas(SomeEntity, SomeEntityData) transforms: SomeEntityData[]
|
|
|
|
|
- autorun() {}
|
|
|
|
|
- render() {
|
|
|
|
|
- return <div></div>
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-## FlowNodeEntity
|
|
|
|
|
-- 节点是一颗树,在自由画布模式,则节点是扁平的,无子节点
|
|
|
|
|
-```ts
|
|
|
|
|
-inteface FlowNodeEntity {
|
|
|
|
|
- id: string
|
|
|
|
|
- children?: FlowNodeEntity[]
|
|
|
|
|
- pre?: FlowNodeEntity
|
|
|
|
|
- next?: FlowNodeEntity
|
|
|
|
|
- parent?: FlowNodeEntity
|
|
|
|
|
- collapsed: boolean // 是否展开
|
|
|
|
|
- getData(dataRegistry): NodeEntityData
|
|
|
|
|
- addData(dataRegistry)
|
|
|
|
|
-}
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-## 2.4.4 FlowNodeTransformData 节点的bbox
|
|
|
|
|
-
|
|
|
|
|
-```ts
|
|
|
|
|
-class FlowNodeTransformData {
|
|
|
|
|
- localTransform: Matrix, // 相对偏移, 只相对于同一个Block的上一个Sibling节点的偏移
|
|
|
|
|
- worldTransform: Matrix, // 绝对偏移, 相对于Parent和Sibling节点叠加后的偏移
|
|
|
|
|
- delta:Point // 居中居左偏移, 和Matrix独立,每个节点自己控制
|
|
|
|
|
- getSize(): Size, // 由自己(独立节点) 或者 子分支节点宽高间距计算得出
|
|
|
|
|
- getBounds(): Rectangle // 由worldMatix及 size 计算得出, 用于最终渲染,该范围也可用于确定高亮选中区域
|
|
|
|
|
- inputPoint(): Point // 输入点位置,一般是Block的第一个节点的中上位置(居中布局)
|
|
|
|
|
- outputPoint(): Point // 输出点位置,默认是节点中下位置,但条件分支,是由内置结束节点等具体逻辑判断得出
|
|
|
|
|
-}
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-## FlowNodeRenderData 节点内容渲染数据
|
|
|
|
|
-
|
|
|
|
|
-```ts
|
|
|
|
|
-class FlowNodeRenderData {
|
|
|
|
|
- node: HTMLDivElement // 当前节点的dom
|
|
|
|
|
- expanded:boolean // 是否展开
|
|
|
|
|
- activated: boolean // 是否激活
|
|
|
|
|
- hidden: boolean // 是否隐藏
|
|
|
|
|
-}
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-## FlowDocument
|
|
|
|
|
-
|
|
|
|
|
-```ts
|
|
|
|
|
-interface FLowDocument {
|
|
|
|
|
- root: FlowNodeEntity // 画布的根节点
|
|
|
|
|
- fromJSON(data): void // 导入数据
|
|
|
|
|
- toJSON(): FlowDocumentJSON // 导出数据
|
|
|
|
|
- addNode(type: string, meta: any): FlowNodeEntity // 添加节点
|
|
|
|
|
- traveseDFS(fn: (node: flowNodeEntity) => void, startNode = this.root) // 遍历
|
|
|
|
|
-}
|
|
|
|
|
-```
|
|
|