雲鳳蝶自由畫布之道:分層模型

blank

雲鳳蝶自由畫布之道:分層模型

概述

雲鳳蝶是一個hpaPaaS,目標是為中後台應用研發提供簡單、高效、高質量的研發方案。在雲鳳蝶的自由畫布、屬性面板和數據驅動等特性的支持下,不僅是前後端,甚至PD、設計師都能直接參與研發工作。

這篇文章就來分享下,雲鳳蝶的自由畫布之道。

blank

在雲鳳蝶的自由畫布里,一切都是分層的。最底下是諸如antd 等畫布組件的渲染層,往上是錯誤報告層、框選層、右鍵菜單層、對齊線層、間距線層、選中/鎖定邊框等等非常多的交互層。

例如,畫布的交叉錯誤紅色警告、參考線、標尺:

blank

選中/鎖定邊框:

blank

右鍵菜單:

blank

直觀上看,交互層是這樣的結構:

blank

這種結構是雲鳳蝶自由畫布迭代了無數遍之後沉澱下來的。它把畫布從頂層劃分成了渲染和交互兩個方面。渲染層只負責把組件渲染到畫布上,而交互層才是真正承載用戶操作的地方,實現複雜業務功能的分層治理。

渲染層

雲鳳蝶畫布的渲染層只負責組件渲染一件事,它不涉及用戶操作。

畫布組件都由HOC 高階組件包裹過,這個高階組件做兩件事情:

  1. 傳遞真實的props 給畫布組件
  2. 響應用戶配置數據變化
blank

交互層

雲鳳蝶畫布的交互層真正承載了與用戶的交互,比如錯誤報告、參考線等訊息展示,框選、右鍵菜單等點選操作。

PositionMonitor 和EventBus

真實業務場景裡,用戶和畫布會產生非常多非常細的交互過程:

  1. 用戶點擊鼠標的時候,畫布要知道用戶點了哪個組件
  2. 用戶框選組件的時候,畫布要知道框選了哪些
  3. 組件所在位置上要渲染參考線、報錯訊息等,而且拖拽組件的時候訊息能跟隨拖拽
  4. ...

基本所有的交互都依賴一些關鍵訊息:

  1. 畫布組件的坐標
  2. 用戶在組件上產生的event 事件,比如MouseEvent、DragEvent 等

而畫布的交互層抓取到這些訊息後,就可以做相應的操作了。這實際上是個渲染層和交互層通信和狀態共享的過程,所以畫佈設計了PositionMonitor 和EventBus 來處理,如下圖所示:

blank

EventBus 是個經典的事件總線。用戶的交互事件默認作用到了畫布組件渲染層。渲染層通過EventBus 拋出事件給交互層。交互層接到事件後進行自己的業務操作。

PositionMonitor:基於瀏覽器MutationObserver的畫布組件坐標收集機制。當畫布組件位置變化時,就會觸發PositionMonitor調用getBoundingClientRect方法,收集組件坐標。

可觀察模型驅動視圖

畫布的交互性要求非常高,各種交互狀態要及時響應。比如組件拖拽的時候,對齊線、間距線、等距線等都要高性能實時繪製,否則會產生拖拽卡頓感。

React 經典的淺比較props 自頂向下更新虛擬dom 的方式已經不太能滿足畫布複雜狀態下也要保持高性能的需求,所以畫布組件內部同樣採用了雲鳳蝶可觀測DDD 充血模型驅動視圖的機制。

雲鳳蝶的模型驅動視圖機制:定義一個可觀測的DDD 充血模型,當模型數據改變時,相應的React 組件自動forceUpdate 更新視圖。這種方式可以讓UI 視圖精確響應數據變化更新。

工程實現上,每個層都可以對畫布暴露可觀察的Model,然後畫布會把這些Model 引用統一掛到內部的$model 屬性上,架構就變成如下圖所示:

blank

blank

$model 是畫布的頂部屬性,共享給了所有畫布層,完成了兩件事情:

  1. 層與層之間的狀態共享
  2. 模型驅動視圖精確更新畫布層

只要畫布層代碼上訪問了$model 上的字段,雲鳳蝶就通過依賴收集知道了畫布層依賴$model 的字段,數據變化自然而然精確觸發相應畫布層的視圖更新,而沒有訪問$model 的畫布層則不更新,避免性能損耗。

UI 視圖堆疊模式

通常情況下,交互層視圖會100% 蓋在渲染層上面,然後通過讀取組件坐標來定點繪製交互所需要的訊息。例如間距線、對齊線、框選線等。直觀上看大概是這樣:

blank

這種視圖堆疊模式能解決絕大部分的視覺需求,但為了達到更極致的視覺表現力,單一的視圖堆疊模式還不夠:

  1. 組件坐標收集過程有一定的延時。如果交互視圖強依賴了組件坐標,那也會產生延時,直觀上的體驗就是交互視圖跟隨不流暢。
  2. 交互視圖會始終覆蓋在組件渲染層上方,做不到畫布組件蓋住交互視圖的效果。例如,選中的組件外圍要有藍色的邊框,而邊框卻被另一個組件蓋在了下面,如下圖所示。

為了達到更極致的視覺表現力,畫布目前一共設計了4 種視圖堆疊模式:Layer、InstanceLayer、WrapperLayer 和ToolBar,整體結構如下圖所示。它們分別實現了交互視圖的畫布覆蓋、組件覆蓋、畫布包裹、工具條展示功能。只要通過適當的組合,基本上可以實現任意複雜度的視覺需求。

blank

在工程實現上,一個交互層可以同時應用多個視圖堆疊模式:

blank

結語

本文主要介紹了雲鳳蝶自由畫布的分層模型。在分層的視角下,組件渲染和各種交互操作都分門別類依次碼放在不同的畫布層,達到了較好的維護性和較高的性能。

自由畫布是低代碼建站的重要武器,未來還將開放一鍵擺放、智能佈局等更加傻瓜化的頁面搭建能力。


未來已來,時不我待!

雲鳳蝶招聘前端、Java、PD、設計崗位,未來等你共創!

如果你感興趣,歡迎聯繫[email protected][email protected]

What do you think?

Written by marketer

blank

SEE Conf 大會邀請函| 體驗美好,玩轉數據

blank

乾貨| 第十四屆D2 前端技術論壇20+ 份精彩演講PPT 分享