LogicFlow深度探究之旅🚀

2,461 阅读4分钟

我正在参加「掘金·启航计划」

这篇文章中,我们已经了解了目前市面上常见的一些画布引擎

  • Drawio:33.1k⭐
  • Xflow:364⭐
  • LogicFlow:3.8k⭐

本文就准备详细探究关于 LogicFlow 的整体设计理念和方案,从而可以知道它为什么会成为热门开源项目的原因,废话不多说,开始吧~

kaihei.jpg

正文

本篇文章主要分为如下几个部分

  • 技术栈方案选择
  • 画布的组成
  • 扩展的实现
  • 事件系统详细设计
  • 画布模块详细设计

技术栈方案选择

LogicFlow代码仓库采用了目前最流行的 monorepo 的方式,结合 lerna 进行管理,分为两个package:

  • core
  • extension

前端技术选型为

  • Preact
  • mobx

画布的组成

画布的组成.png

通过上图,我们可以看到画布由两部分组成

  • 基础画布:这部分提供了画布编辑的核心功能,列举如下

    • 图形的绘制能力:基于 SVG 来绘制形状各异的节点和线,并提供了基础的节点(矩形、圆形、多边形等)和线(直线、折线、曲线)
    • 各类交互能力,让图动起来:根据节点、线、画布的各类鼠标事件(hover、点击、拖拽等)做出反应。比如节点拖拽、拖拽创建边、线的调整、双击节点编辑文本等
    • 提升编辑效率的能力:提供网格、对齐线,上一步、下一步,键盘快捷键,画布放大缩小等配套能力,帮助用户提升编辑效率
  • 扩展:基于特定的业务场景,拓展能力边界,列举如下

    • 自定义节点和边:用于自定义节点和边的样式,并且对于节点还可以设置连接规则
    • 自定义组件:常见的如 节点拖拽生成栏属性编辑栏预览图 等都可以通过自定义组件的方式提供

扩展的实现

在上一节中,我们聊到了扩展是LogicFlow的重要特性,那如果我们想做一个自己的扩展,应该如何去实现呢?

inte.jpg

具体来说分两方面

  • 自定义节点和边
  • 自定义组件

自定义节点和边

图片3.png

图片2.png

对于节点和边,我们需要通过 继承 的方式去实现,在LogicFlow里,提供了边的节点的baseClass,需要注意的是继承的时候,需要同时继承 viewmodel,这是因为LogicFlow采用 mobx 来管理应用状态,整体是基于 mvvm,因此就需要定义视图和数据模型

  • 节点

    • view:BaseNode,封装了大部分交互逻辑,如拖拽、点击等
    • model:BaseNodeModel
    • view:BaseEdge,封装了大部分交互逻辑,如拖拽、点击等
    • model:BaseEdgeModel

给一个代码示例

图片1.png

自定义组件

自定义组件由于需要插入额外的dom元素,因此在实现时,需要提供 render 函数来提供插入,关键代码如下

图片4.png

事件系统详细设计

图片5.png

LogicFlow里采用的是 发布订阅模式 进行内部事件的管理,因此存在一个事件中心,用于存储与下发不同的事件,下面是事件中心的部分源码截图

图片6.png

借助它,就可以将画布与扩展进行解耦,双方的所有通信都通过事件中心来转发,这样就可以更容易对所有事件进行集中管理,从而实现许多功能,比如打印日志,事件重放等

画布模块详细设计

LogicFlow里的画布分层结构大致如下

图片7.png

其中 画布层 是核心,是用来实际渲染节点和边的层,其它层都是扮演辅助角色

  • 工具层:承载编辑节点或边时的文本
  • 辅助层:拖拽节点时,显示对齐线的地方
  • 网格层:辅助显示拖动节点或边的距离
  • 背景层:用于显示自定义背景,位于最底层

下面是层级分布的实际代码截图

图片9.png

结语

相信通过本文的阅读,你已经对画布引擎项目的设计方案有很深刻的认识了,未来在遇到画布引擎方案的选择时,心里肯定会更加有底气😉

所以都看到这里了,希望你能给我一个免费的赞👍,听说点赞的人都会升职加薪哦🤩