2C 設計稿轉代碼是怎么實現的?自己做一個可行嗎?
D2C 是指 Design to Code,設計稿轉代碼,輸入是 sketch、figma、PSD 等設計稿,輸出是 vue、react、小程序等各平臺的前端代碼。
對前端工程師來說,如果能直接把設計稿轉成可用的代碼,是非常有意義的,那這樣一個工具是怎么實現的呢?
vue、react 等各平臺的前端代碼都可以通過一種樹形數據結構來描述,比如 vdom。當然這里不是用 vdom,而是需要設計一種中間數據結構,叫做 DSL(領域特定語言),專門用于描述界面結構的一種語言。
也就是說我們要把從設計稿中提取出的信息轉成中間的 DSL,然后再通過 DSL 打印成各種代碼。
那怎么從設計稿提取信息呢?
其實 figma、sketch 等的設計稿都是矢量的,也就是由各種圖形組合而成,它們設計稿的存儲也是 json 格式的:
下面就是一個 figma 設計稿的存儲結構:
可以看到是一個節點的樹,通過 children 關聯子節點,每個節點有 type 和位置信息。
比如 TEXT 節點有 absoluteBoundingBox 的位置信息 x、y、width、height,有 fontSize、fontFamily 等文本樣式信息:
比如 RECTANGLE 節點有 fills 信息表示背景,如果是 image 類型的 fill 會有圖片的 hash 來關聯到圖片。
這些所有的節點都是可以對應到 DOM 節點的,樣式也可以對應到 CSS。
所以,只要把設計稿的樹形存儲結構,轉為描述頁面的 DSL,然后打印成各平臺的代碼就可以了:
看起來好像挺簡單的?
這只是理想的情況下,實際上有很多問題沒處理。
比如布局,按照從設計稿提取的信息來布局,只能做成絕對布局,這樣的代碼是不好維護的,我們要轉成 flex 布局。
比如結構,現在是直接把設計稿結構轉換成了 DOM 結構,實際上設計稿的層次結構不一定合理,需要轉成適合網頁的結構。
有了絕對的位置,轉換成 flex 布局可以使用投影法:
比如左邊這樣的布局,水平投影到右側,可以分成兩組,上面一組,下面一組,投影的間距可以設置為 margin-top、margin-bottom:
每一組分別豎直投影,可以算出每個元素的間距,分別設置為 margin-left、margin-right:
然后元素內部也這樣做投影,分別設置 padding-left、padding-top 等。
這樣就可以把絕對定位的布局轉換為 flex + margin + padding 的布局,代碼可維護性會更高。
再就是分組,這個可以手工搞,提取完設計稿信息之后做一個編輯功能,可以自己調整分組:
但這要求使用者要了解前端需要什么樣的結構,還是有一些要求的,能不能自動調整分組呢?
這就需要 AI 算法的介入了,這里需要聚類算法。
此外,生成的前端代碼是要有 className 的,這個 className 起的是否語義化也是可維護性的一個重要的方面。
這個問題也有兩種解決方式,一個是手工標注,一個是 AI 算法生成。
手工標注就是使用者在設計稿中添加一個名字的標識,比如這樣:
再就是通過算法來識別不同類型的組件,加上語義化的名字了。
還有一個問題就是現在只能轉換成 text、image 這種基礎組件,很多時候我們是有組件庫的,比如可能會用 antd。
能不能直接把設計稿轉換成基于組件庫的代碼呢?
可以的,其實這就是個對應關系的問題,如果我們能把不同的節點識別為不同的組件,從中提取不同的參數信息,之后不就可以生成對應的組件代碼了么?
這種組件標注同樣也有人工和 AI 自動標注兩種方式:
通過 AI 來識別出不同的組件,然后打上自動打上標記,或者通過編輯器來人工打標記。
這個編輯器可以是通過 sketch 插件、figma 插件的形式在設計軟件里做,也可以是一個獨立的 web 平臺來做。
這個編輯器完全可以對接低代碼編輯器,也就是可以拖拽一些組件進來,再生成 DSL,然后打印成代碼。
不過設計稿轉成的 DSL 不是全部由組件構成,和低代碼的 DSL 還是有區別的。
這就是設計稿轉代碼的實現原理了,理想情況下,直接把設計稿結構轉成 DSL 的結構,生成 flex 布局和對應的組件信息,然后打印成代碼就可以。
但很多情況下,設計稿多少存在一些問題,需要人工編輯或者 AI 自動處理的方式來調整分組、className、標注組件等,很難做的通用。
而且我們是直接從結構化存儲的矢量設計稿開始處理的,如果是從圖片開始,那需要通過 AI 的方式先把其中的信息提取出來,再轉成 DSL,這樣多了一步用到 AI 的地方。
D2C 的原理還是挺清晰的,但是能夠做的多智能,上限取決于 AI 算法,當然,下限可以通過做一個編輯器來人工干預來保證。
原理理清了,我們再來過一遍現有的各種 D2C 的產品:
Picasso
先看一下 58 的 picasso,他提供了一個 sketch 設計稿轉代碼的 sketch 插件:
直接把設計稿信息轉成 DSL,然后打印成代碼了,沒有做編輯器,所以用起來比較簡單,
但是不能人工干預。
看下它的源碼分包,也是設計稿信息轉成 DSL,做分組和布局的處理,然后打印成代碼的流程:
它支持生成使用絕對布局的運營版代碼,也可以生成使用 flex 布局的可維護性比較高的代碼。
我試了一下,還原度還可以:
設計稿是這樣:
Picasso 生成的 flex 布局的代碼是這樣:
結構和樣式還原度還行。
再用 Picasso 生成運營版代碼是這樣:
所有元素平鋪,布局使用絕對定位。
這樣的代碼還原度更可靠一些,但是代碼基本沒啥可維護性,做做活動頁還可以。
總體看下來,Picasso 沒有使用 AI 算法,只是做了 sketch 設計稿數據到 DSL 的轉換,處理了下分組和布局轉換,同時支持絕對定位和 flex 布局,然后打印成各種代碼。
沒有支持編輯器、也沒有做 className 的處理,對組件標注的支持也不好。
Deco
再來看下京東的 deco,它也是支持 sketch 設計稿轉各平臺代碼。
不過它提供了一個 web 版的工作臺,可以選中畫板,點擊導出數據,之后瀏覽器會打開工作臺:
導出完成后會提示你到工作臺粘貼:
然后會在工作臺展示設計稿信息轉換之后的 DSL 和生成的頁面的預覽,可以修改 DSL 之后再生成代碼。
還原度也還行,生成的是 flex 布局的代碼。
當然這只是它公開的部分,內部版本據說支持了組件標注、數據注入、事件綁定等邏輯層的東西,可以直接產出包含了包含了布局和邏輯的可用代碼。
整體看下來,Deco 做的比 Picasso 更完善,內部版本實現了編輯器,支持 flex 布局計算,組件標注、通過 AI 算法實現了通過聚類來自動分組、通過推理引擎生成語義化的 className 等,編輯器甚至還支持了邏輯層的處理,可以生成完整的前端代碼。
CodeFun
Code Fun 是國內專門做設計稿轉代碼的創業公司,因為是通用工具,所以它們支持的平臺更多, 提供了 Sketch、PSD、Figma 等的插件來上傳設計稿數據,支持生成的代碼也包含的更多,包括 vue、react、uni-app、taro、小程序等,不過現在只是移動端,桌面端后續也會支持。
可以在 Figma 里上傳設計稿:
然后在編輯器里打開:
可以標注組件、可以切換 flex 布局和絕對布局,可以手動分組、編輯樣式,之后預覽或者下載代碼。
可以人工干預的地方比較多,當然,他們也做了一些 AI 的智能處理。
整體看下來, code fun 支持的平臺更多,支持的人工干預手段更多,可以手動編組、標記組件、切換布局方式等,下限比較高。
Imgcook
Imgcook 是淘寶開源的設計稿轉代碼的工具,支持 figma、sketch、psd,甚至還支持圖片。
除了通過插件上傳數據外,也可以直接上傳設計稿文件。
通過插件上傳數據,還可以做一些分組和切圖的標記:
然后在 web 的編輯器里打開,也可以直接導出代碼:
可以編輯樣式、屬性、綁定事件等,但是這還原度一言難盡:
總體來看,imgcook 支持的設計稿類型比較多,甚至支持從圖片來提取信息,也提供了編輯器功能可以做一些人工干預,功能還是比較全面的。
Locofy
Locofy 是國外的設計稿轉代碼的工具,支持 figma 設計稿轉 react、react native、next.js、gatsby 等代代碼。
支持 next.js 和 gastby 這點就可以看出是國外的工具了。
它的編輯器是在 figma 插件里實現的,而不是獨立的 web 工作臺:
可以手動標注組件,然后設置屬性。
還有低代碼編輯器的功能,可以直接拖拽組件進去:
手工標注比較麻煩,locofy 也支持 AI 自動標注組件。生成的代碼也可以選擇使用不同的技術:
生成代碼之后會在 web 平臺預覽代碼,可能是因為這個在 figma 插件里做不大好吧:
之后可以導出代碼,或者一鍵部署。
總體看下來,locofy 對組件標注的支持做的挺好的,也支持了低代碼的方式編輯,并且都是在 figma 里做的,這是和其他工具的一個很大的區別,其他工具都是在 figma 里上傳設計稿數據,然后在 web 的編輯器里處理,這樣能跨各種工具復用,而 locofy 可能就只想支持 figma 吧,所以在 figma 插件里做了很多功能。
知道了 D2C 的實現原理和已有的各種實現,那我們自己實現一個符合自己需求的 D2C 工具可行嗎?成本高么?
其實還是挺高的,做的足夠通用很難,但就算不需要特別通用,只支持某些業務場景,也大約需要一到兩個人一年的時間去全職搞這個。這對于小公司來說是很高的成本了,ROI 比較低。但是對中大規模的公司來說,能夠用在很多項目上,ROI 會相對較高,就值得投入人力長期去做了。
這也不是我個人的觀點,是轉轉的一篇文章里提到的:
總結
設計稿轉代碼的原理是從結構化的矢量圖中提取信息,轉換成中間 DSL,然后再生成各平臺的代碼。
從設計稿轉 DSL 的過程需要處理分組、做絕對布局到 flex 布局的轉換,生成語義化的 className,支持組件的標注。
這個過程可以通過編輯器來實現人工干預,也可以通過 AI 來智能化處理。
下限是編輯器人工干預保證的,上限就要靠 AI 了。
然后我們看了一下各種 D2C 工具:
58 的 Picasso 沒有支持編輯器,組件標注支持的也不好,但是支持生成絕對布局和 flex 布局的代碼,還原度也還行,并且是開源的
京東的 Deco 支持了編輯器,通過 AI 做了很多自動化的處理,還支持了邏輯層的處理,但是目前公開的部分還比較簡單,也沒開源
淘寶的 imgcook 支持的設計稿類型比較多,還支持從圖片來提取信息,也支持了編輯器,在里面實現了低代碼的組件拖拽編輯,功能比較全面
專門做 D2C 工具的 CodeFun 做的比較通用,支持各種矢量設計稿(不支持圖片),也支持生成很多種代碼,編輯器功能也挺多,還原度不錯,只不過是收費的,沒開源
國外的 Locofy 只做 figma 轉 react 系列技術棧,所以在 figma 插件里做了很多功能,比如組件標注、低代碼編輯,之后在 web 預覽代碼,還可以一鍵部署
這些 D2C 工具其實都不夠通用,要支持自己的一些需求估計還得自研,但是自研一個 D2C 的工具還是需要挺高的成本的,對于中大公司來說,如果業務場景比較合適,ROI 還行,還是值得長期去做的。