當前位置:
首頁 > 最新 > 如何構建一個理想UI代碼表達的自動化工具?

如何構建一個理想UI代碼表達的自動化工具?

基於設計師產出的 Sketch,甚至是一張 PNG,就能自動生成高可維護可擴展的 UI 代碼,質量堪比一位資深前端工程師, 一定是一件讓整個大前端領域都為之尖叫的事情。

出於這樣一個讓人興奮的命題,閑魚團隊打造了 ui-automation 工具 。


背景

如何讓前端,客戶端的 UI 開發更有效率,一直是一個大前端領域熱門話題。 從純手寫 UI 代碼,到編寫 XML 表達 UI,到所見即所得的 UI 編輯器。每一步都在極大提升著大前端領域的生產效率。 當下,隨著計算機視覺技術,深度學習技術在工程側的大量使用,閑魚團隊的同學們認為,基於當前的技術,是完全能夠完成接近甚至超越資深前端工程師編寫的理想的 UI 表達。


類比基於傳統的掃描演算法和最新的 pix2code 的深度學習技術。它們確實在有些場景下,生成了渲染完全一致的 UI 代碼,但是往往可維護性可擴展性差,除了在簡單的靜態頁面中能有所應用,在大部分需要動態能力的場景,無能為力。 核心的生成的 UI 代碼質量問題,是之前的這些工具無法跨越的鴻溝。 而閑魚的 ui-automation 最核心的是要解決代碼質量問題,使得生成的 UI 表達是最理想的,真正解放開發同學。


信息提取 => 2. DSL 推導 => 3. 目標平台代碼

相比於渲染流程

ui 代碼 => 2. gpu 渲染 => 3. 畫面

是一個逆向的流程。


基於 Skecth 信息的提取和預處理 信息全,精確,但是有冗餘,干擾信息。

基於圖片信息的提取 信息乾淨,沒有冗餘信息。


將扁平化的上游信息,樹形化,同時補充了完整的布局約束的信息。


根據上游的 DSL 信息, 生成不同平台的目標代碼,如 flutter,weex 等。


基礎 UI 元素

我們定義了 3 中最基礎的 UI 元素 Shape,Text, Image。

結構上一個基礎 UI 元素有一下幾部分構成:

內容

渲染樣式

布局樣式 布局樣式沿用了經典 flexbox 的模型。


輸入中包含了上述 3 類基本的 UI 元素, 包含它們的內容,它們的渲染樣式,以及相對屏幕的絕對坐標和大小,其中層級結構和布局屬性在演算法的推導中給出。


輸出是一個類似 dom 樹的結構,有完整的布局屬性,除了上述三類基礎元素外,還有基礎容器組件,CI 組件,BI 組件。

在 DSL 的推導過程中, 分兩大層

分組層關注於宏觀信息的處理。目標是完成一棵最佳的 ViewTree,以及掃描出足夠的輔助信息給下一層屬性推導使用。

(1)二元切分 對一組元素進行劃分的時候 任何元素之間可能存在如下兩種關係 1. 父子關係 2. 兄弟關係 根據兩種關係的特點,我們使用了兩個不同的模型來對數組切割(一分為二)。 1. 父子關係使用重合模型來劃分。 重合模型會突出明顯的若干個 background|foreground 圖層 在 x,y 兩個方向上都重合了剩下的所有元素。 2. 兄弟關係使用投影模型來劃分。 投影模型,通過往一個方向上投影,兄弟關係的元素間 會存在明顯的獨立且連續分布的規律。兩個方向都可投影的情況下, 優先水平方向。 在對重合模型和投影模型做適度優化後,第一次分組的容錯性,穩定性,準確性得到了極大的提升。

一個簡單的遞歸偽代碼

經過上步驟切分後, 得到的是一棵標準意義上的二叉樹。

例一: 註:7 號元素是簡化的處理,實際包含了 3 個基礎元素。 輸入:

輸出:

這樣的一棵二叉樹。

(2) 歸併 標準意義上的二叉樹, 並不符合我們的需求,所以需要做一次扁平化的歸併,將同方向的父子節點歸併為一個數組, 降低樹的深度。 一個簡單的遞歸偽代碼

經過這層處理上例一的樹修正為

(3) 排序層 根據容器方向,做一輪左到右,上至下的排序。

(4) 感知輔助線 對 ViewTree 做一次深度遍歷, 掃描出輔助線的信息,將影響後續的對齊方式的推導,但並不影響 ViewTree 結構。如上圖, 灰色框表示基礎元素,紅色框比較容器,黃色虛線表示掃描出輔助線的信息。因為有輔助線信息的存在,我們才能讓第 3 行的文字,左對齊,而非右對齊。人的視覺信息處理亦是如此。

(5) 疏密切分 根據疏密分布, 在對同一容器下的孩子節點,根據疏密分布切分。如上圖,同在水平方向的兄弟節點,根據疏密關係,分解為左族群和右族群,一個向左對齊,一個向右對齊,中間的剩餘空間是共享的。

(6) 掃描網格分布信息 這裡用到圖形相似度的演算法,若干水平行, 每行的元素子樹之間相似。 在垂直方向掃描得到最大不重複的組合, 打破原有層級約束重新組合。 如:

掃描後, 打破原有層級約束後, 重新組合

(7) 感知中間線 對 ViewTree 做一次深度遍歷, 掃描出有效的中間線信息,會影響 ViewTree 結構。

(8) 合併層 1. 合併背景圖層到容器的背景屬性 2. 合併背景圖層到 Text 的背景屬性 3. 合併僅包含一個孩子節點的容器

大致經過上述 8 個小層的處理後, 我們得到了一個理想的 ViewTree。下一步開始我們的屬性推導。

屬性推導層關注於局部信息的深度推演。

(1) 推導每一個容器的方向 推導方向是最獨立的,僅僅依賴於孩子節點的分布情況。

(2) 推導每一個節點是 在流裡面的,還是脫離流絕對的 這裡依賴一個重合衝突演算法。大體是重合衝突率高的,就是絕對的元素,重合衝突率低的是流式元素。同時存在一定的冗餘能力,允許小部分的重疊(負 margin),這樣極大的提高了線性布局的動態性。

(3) 推導每一個節點的大小。 以一個儘力撐滿的貪心模型,推導出每一個元素的大小。同時儘力用屬性約束取代直接給定寬或定高的形式,來達元素大小是到跟隨內容或跟隨孩子節點或跟隨父容器的動態性。 對於一個容器的副軸的大小的處理,會略微複雜些,

(4) 推導出一些特殊布局

網格

左右對齊布局 等

(5) 推導主軸方向對齊方式 優先居中, 其次居左, 最後居右。

(6) 推導副軸方向對齊方式

(7) 推導位置

流式元素 通過 margin 表示坐標。 居中通過(5)(6)推導的 JustifyContent,AlignItems,AlignSelf 等要素描述。

絕對元素 通過 left, top, bottom, right 等描述坐標。居中通過 transform 描述。

(8) 推導 padding

ui-automation 工具目前已經運用在閑魚內部的各個業務場景之中,伴隨著大量的應用,工具本身同樣日益進化。

最後,閑魚技術團隊廣招各類方向的達人,無論你是精通移動端,前端,後台,還是機器學習,音視頻,自動化測試等,都歡迎投遞簡歷加入我們,一同用技術改善生活!簡歷投遞:guicai.gxy@alibaba-inc.com

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 全球大搜羅 的精彩文章:

這世上總有人愛你如生命,致我最愛的小凱哥哥!
《銀魂》與《頭號玩家》:信息時代分眾社會中的neta影視江湖

TAG:全球大搜羅 |