近期時不時地會想「反混沌前端工程」當前比較重要且優先的兩塊事情:控件(UI 組件)體系 Petals 和通用塊編輯器。
大部分人不會認為這兩者之間有什麼聯繫,然而在我眼中關係可大了去了——它們的「本質」可以近似看作是一個東西。
控件可以認為是當下 GUI 開發的重要基礎設施和基本單元,而在塊編輯器體系中則是「塊」,理論上「塊」就是控件,是被注入特殊狀態的控件——好比一個被施了法術的人成為提線木偶一般。
那麼,直覺告訴我 Petals 可以跟塊編輯器打通,將更為抽象的「塊」作為基礎設施;這裏的「塊」不是塊編輯器中的「塊」,還是用「block」做區分吧。
回顧並總結這十多年的 GUI 開發經驗來看,GUI 中最基本的元素就是佔據整行的「block」和與文本類內容實際寬度相匹配的區域這兩種,後者我就叫它「text」吧。
在網頁開發中,前者叫「塊級元素」,後者則叫「內聯元素」或「行內元素」。
假設有分別代表平面中水平和垂直方向的 x、y 軸,再加上垂直於它們所構成平面(屏幕)的 z 軸,在元素的堆疊方式上也有兩種:
- 沿 y 軸從上往下堆疊,這時「block」如上面所説默認佔據整行,與「block」重疊的元素可以視為是在其內部,就像中間挖了個槽;
- 沿 z 軸自底向頂堆疊,這時「block」與「text」沒太大分別,都是差不多的矩形,與它們重疊的元素就是像摞衣服一樣一層壓着一層。
第一種堆疊方式就是很常見的 GUI 渲染方式,也是塊編輯器中的佈局方式;第二種則多用於畫布類可以自由排列組合的場景。
這兩種方式並不是非此即彼,它們經常一起使用,只不過是以其中一種為主。
説了這麼多,打通 Petals 與塊編輯器的關鍵點就在於——
用「block」和「text」作為基本單元構建起 Petals 這個控件體系,並且它們的行為是可被注入的,為被外部「操控」留下口子:
interface IInjectableElement {}
// Block-level element
interface IBlock extends InjectableElement {}
// Inline-level element
interface IText extends InjectableElement {}
function createInjectableElement<E extends IInjectableElement = IInjectableElement>(): E {}
沒被注入時,默認行為就跟常規控件一樣;而被注入後,控件就成了提線木偶被外部庫或框架所控制,比如變成了塊編輯器中的「塊」。
本文其他閲讀地址:個人網站|微信公眾號