oceanzhu 3fb880d09b refactor(stage):重构魔方编辑器stage代码
Squash merge branch 'feature/oc_actionbox_879360293' into 'master'
    对魔方编辑器核心代码stage进行重构,这部分代码主要是负责编辑器中间画布区域的处理,包括渲染一个所见即所得的画布,支持组件的增删改查和拖拽、高亮操作。
    旧代码存在的问题以及解决方案:
    1、过多暴露属性和循环引用,导致stageCore、stageDragResize、StageMultiDragResize、StageRender、StageMask、StageHighlight之间形成复杂的网状依赖,非常不可控。StageCore负责创建后面5个类的实例,并把这些实例作为自己的公共属性,同时core把自己的this传给这些实例,这些实例就会通过core传进来的this,通过core间接的访问其它实例的方法和属性,比如在stageDragResize中可能存在这样的一个访问:this.core.stageRender.contentWindow.document
    解决方案:
    1)、属性尽量设置为私有,对外暴露方法,不暴露属性;
    2)、core避免向其它类传递this,改为传递接口,需要什么就传什么

    2、事件传递较多,跳来跳去,定位问题较为困难
    解决方案:
    重新梳理各个类的职责,尽量在类中闭环,减少事件传递。
    新增了actionManager类,core负责管理render、mask、actionManager三个类;
    actionManager负责管理单选、多选、高亮三个类,同时将mask中的事件监听,转移到actionManager监听,actionManager形成单选、多选、高亮行为后,直接调动单选、多选、高亮完成功能。

    3、存在一些重复代码
    主要是拖拽框的代码在单选、多选、高亮中各自维护,改为统一维护

    4、多选不支持辅助线对齐
    将单选中的moveableOption管理逻辑抽取出来成为单选和多选的父类,使多选支持辅助线对齐

    本次改动取消了一些对外暴露的属性,moveableOption回调函数签名也有变化,详细情况如下:
    删除stageCore公共属性:
    public selectedDom: HTMLElement | undefined;
    public selectedDomList: HTMLElement[] = [];
    public highlightedDom: Element | undefined;
    public dr: StageDragResize;
    public multiDr: StageMultiDragResize;
    public highlightLayer: StageHighlight;
    public config: StageCoreConfig;
    public zoom = DEFAULT_ZOOM;
    public containerHighlightClassName: string;
    public containerHighlightDuration: number;
    public containerHighlightType?: ContainerHighlightType;
    public isContainer: IsContainer;

    stageCore入参改动:
    这两个参数原本定义:
    moveableOptions?: ((core?: StageCore) => MoveableOptions) | MoveableOptions;
    multiMoveableOptions?: ((core?: StageCore) => MoveableOptions) | MoveableOptions;
    修改后定义:
    moveableOptions?: CustomizeMoveableOptions;
    multiMoveableOptions?: CustomizeMoveableOptions;
    CustomizeMoveableOptions =
      | ((config?: CustomizeMoveableOptionsCallbackConfig) => MoveableOptions)
      | MoveableOptions
      | undefined;
    export interface CustomizeMoveableOptionsCallbackConfig {
      targetElId?: string;
    }
2022-11-24 21:19:56 +08:00
..
2022-06-07 16:25:41 +08:00
2022-11-24 21:04:33 +08:00

画布功能介绍

画布是编辑器中最核心的功能,处理组件拖拽和所见即所得的展示。

画布整体功能示意图

魔方编辑器 如上图所示,中间粉色区域及其周边的标尺,是画布区域,就是这个模块代码要处理的内容。

已选组件的组件树

已选组件列表 已选组件列表,组件列表也可以单选、多选、高亮、删除、拖拽组件到容器内

画布支持的功能

  • 渲染runtime
  • 从编辑器增加组件,可以在左侧组件列表中通过单击/拖拽往画布中加入组件
  • 删除组件,在画布中右键单击组件,在弹出菜单中删除;或者在左侧已选组件的组件树中右键删除组件
  • 单选拖拽组件,可以在画布中选中组件,也可以在左侧目录中
  • 多选拖拽组件通过按住ctrl健选中多个组件
  • 拖拽改变组件大小
  • 旋转组件
  • 高亮组件在画布中mousemove经过组件的时候或者在组件树中mousemove经过组件的时候高亮组件
  • 配置组件,单选选中组件之后,右侧表单区域对组件进行配置,并更新组件的渲染
  • 添加/删除/隐藏/显示参考线,通过在标尺中往画布中拖拽,给画布添加参考线,图中两条竖向和一天横向的红色线条就是参考线
  • 辅助对齐,单选和多选都支持拖拽过程中会辅助对齐其它组件,并在靠近参考线时吸附到参考线
  • 拖拽组件进入容器,支持通过在画布中单选,或者在组件树中单选,将组件拖拽进入容器

核心类介绍

StageCore

  • 负责统一对外接口编辑器通过StageCore传入runtime、添加/删除组件、缩放画布、更新参考线和标尺等同时StageCore也会对外抛出事件比如组件选中、多选、高亮、更新runtimeReady等。
  • 管理三个核心类StageRender、StageMask、ActionManager

StageRender

基于iframe加载传入进来的runtimeUrl并支持增删改查组件。还提供了一个核心APIgetElementsFromPoint该API负责获取指定坐标下所有dom节点。

StageMask

mask是一个盖在画布区域的一个蒙层主要作用是隔离鼠标事件避免鼠标事件直接作用于runtime中的组件从而避免触发组件本身的点击事件比如链接组件会跳走。mask在滚动画布时需要保证同步大小。

ActionManager

  • 负责监听鼠标和键盘事件基于这些事件形成单选、多选、高亮行为。主要监听的是蒙层上的鼠标事件通过StageRender.getElementsFromPoint计算获得鼠标下方的组件实现事件监听和实际组件的解构。
  • 向上负责跟StageCore双向通信提供接口供core调用并向core抛出事件
  • 向下管理StageDragResize、StageMultiDragResize、StageHightlight这三个单选、多选、高亮类让它们协同工作

StageDragResize

负责单选相关逻辑拖拽、改变大小、旋转等行为是依赖于开源库Moveable实现的这些行为并不是直接作用于组件本身而是在蒙层上创建了一个跟组件同等大小的边框div实际拖拽的是边框div在拖拽过程中同步更新组件。 这个类的主要工作包括:

  • 初始化组件操作边框初始化moveable参数
  • 更新moveable参数比如增加了参考线、缩放了大小、表单改变了组件都需要更新
  • 接收moveable的回调函数同步去更新实际组件的渲染

StageMultiDragResize

功能跟StageDragResize类似只是这个类是负责多选操作的通过ctrl健选中多个组件多选状态下不支持通过表单配置组件。

StageHightlight

在鼠标经过画布中的组件、或者鼠标经过组件目录树中的组件时会触发组件高亮高亮也是通过moveable实现的这个类主要负责初始化moveable并管理高亮状态。

MoveableOptionsManager

StageDragResize、StageMultiDragResize的父类负责管理Moveable的配置

TargetShadow

统一管理拖拽和高亮框,包括创建、更新、销毁。