前端代碼是怎樣智能生成的——智能插件篇

作爲阿里經濟體前端委員會四大技術方向之一,前端智能化項目經歷了 2019 雙十一的階段性考驗,交出了不錯的答卷,天貓淘寶雙十一會場新增模塊 79.34% 的線上代碼由前端智能化項目自動生成。在此期間研發小組經歷了許多困難與思考,本篇文章將主要向大家介紹,在前端智能化項目中,智能插件的各種應用與作用。

概 述

在一個常見的開發週期中往往遵循着產品需求到交互稿到設計稿再到前端開發的過程。所以在 Design2Code (簡稱 D2C) 項目過程中,設計師負責來設計產品視覺效果和產出視覺設計稿,而前端開發工程師以設計稿爲輸入進行開發。所以同樣地,在前端智能化的過程中,我們需要一種能自動解析設計稿信息的能力來替代傳統的人工分析和摳圖等繁瑣的工作。同時,隨着近幾年主流設計工具(Sketch、PS、XD 等)的三方插件開發能力逐漸成熟,藉助官方提供的 API 能夠比較好得還原一些基本的結構化信息和樣式信息,從而完成對設計稿原始信息的提取。在此篇文章中,我們將以前端智能化的落地產品 imgcook 的 Sketch 插件爲例子,詳細介紹我們是如何通過插件對設計稿做處理,最終導出以絕對佈局爲基礎的元素信息,供下游佈局算法使用。

所在分層

如圖所示,鏈路中的第一層爲物料識別層,設計稿將作爲這一層的輸入。這一層主要是用來識別頁面和模塊中包含的物料的,比如對基礎組件,業務組件和基礎控件的識別,從而輔助進行頁面分割並對下游輸入關於某一元素的相關信息。隨後,設計稿的原始信息 (文件) 將會進入到圖像處理層,這一層主要是通過這篇文章所介紹的插件實現,因爲插件可以注入到 Sketch 或者 Photoshop 等設計工具中從而藉助官方提供的一些能力完成對原始設計稿信息的提取。這一層提取的結果將是一個符合 imgcook 規範的 JSON 結構的數據,內容主要是提取出所有元素的相關信息,包含元素的絕對位置和 CSS 可表達的屬性,最終可以理解以絕對定位爲基礎的模塊和頁面。同時,由於不同設計師可能遵循一些不同於傳統前端開發的規範來組織設計稿的圖層和結構,在圖像再加工層中我們還將藉助計算機視覺和智能化的能力對原始設計稿中出現的圖層再加工。例如過濾掉一些無用的圖層或是合併一些可以當作一個整體的圖層等。

D2C 技術能力分層

技術選型

如圖所示,在對接原始設計稿和獲取原始設計稿信息的過程中,我們主要是使用了 Sketch 官方提供的 JS API 進行開發,對於一些官方沒有包裝 JS 接口的功能,我們藉助於 CocoaScript 對原始 Objective-C 接口進行調用。同時,我們使用了 Webview 技術可以使用前端技術棧來渲染插件界面。我們採用 Skpm Sketch 的插件管理工具的腳手架能力和插件發佈能力。

插件技術選型示意圖

插件圖層處理

插件圖層處理流程

總體流程

如結構圖所示,imgcook Sketch 插件將讀取設計稿,按 Depth-first Search (DFS) 的方式循環遍歷所有類型的圖層,提取圖層的基本信息,包括位置和大小。值得注意的是由於 Sketch 裏 Symbol 的概念相當於它的 Symbolmaster 的子類,可以覆蓋它的 Symbolmaster 的部分屬性,所以對於 Symbol 類型的圖層,我們要找到它的 Symbolmaster,提取相關信息。之後我們會對所有會被蒙層影響的或者被其他圖層覆蓋的元素打標,因爲這兩者會影響到當前圖層的視覺輸出。之後因爲各個類型具體的所擁有的樣式不相同,我們會對 Shape, Image, Text 和其他圖層分別做處理,把相關的 Sketch 屬性轉化爲 CSS 理解的形式。我們對設計師約定了一些設計協議,可以通過在設計稿中不同的命名給圖層指定爲成組或者組件,同時帶出相關組件信息。下面我們挑取這個過程中兩個值得注意的難點進行分別講解。

蒙層處理

在 Sketch 裏蒙層的作用是相當於一個底板,所有在結構上位於其之上的圖層如果區域超出了蒙層,這部分超出的區域就會被截斷。對於蒙層的處理主要有以下幾個不同於正常圖層的點:

  • 由於在 HTML 和 CSS 領域並沒有直接對應的概念,蒙層並不能直接導出相關 CSS 屬性或者 HTML 屬性。

  • Mask 圖層不但會影響自己本身的處理,也會影響其他圖層的視覺,所以遇到 Mask 需要多圖層一起處理。

  • 由於 Mask 的形狀可能是不規則形狀,所以需要考慮如何判斷合理的區域進行截斷。

針對以上難點和精準還原視覺的目的,我們開發了一套算法計算 Mask 和其影響的所有圖層的區域計算和形狀計算,針對區域規則且形狀規則的做 CSS 屬性上的常規截取處理,對於無法使用 CSS 屬性表示的情況對 Sketch 視覺可見的區域進行截圖處理。其中,我們會進行無用圖層檢測,如果一個圖層在它的 Mask 區域之外,則此圖層將被視爲無用圖層被刪除,同時,如果一個圖層完全在它的 Mask 區域內,則此圖層不會被 Mask 影響,按照原有邏輯處理。

智能文字位置校準

相對於其他諸如 Shape 和 Image 圖層的處理, 文字圖層會更復雜一點,原因主要有:

  • 對於 Shape 和 Image 的每一個圖層,我們往往也只需要對應導出一個節點,這個節點包括位置和樣式等屬性,但是對於文字圖層,如果包含多樣式,比如顏色,字號,行高等不同,則需要將一個文字圖層拆分爲多個節點導出。

  • Sketch 有定寬類型的文本框,但是對於 HTML 中 span 等標籤爲行內元素,沒有寬度等信息,所以需要對 Sketch 中的多行文本做拆分。

  • 目前 Sketch 中文字圖層想要得到位置和樣式,需要依賴導出的 SVG 信息,而 SketchSVGExporter 接口導出的 SVG 信息經常出現位置不準的情況。

針對第一個問題,我們對 SVG 信息進行循環檢測,判斷每個 SVG 子節點是否有 CSS 相關的屬性發生了變化,如果有變化,就會新建立一個子節點存儲相關信息。針對第二個問題,我們會對定寬的文本框導出準確的寬度信息還有行數信息,佈局算法會針對此信息作出正確的判斷。重點來講一下第三個問題,由於 svg 信息在對於富文本的情況下會不準確的情況,我們設計了一套基於計算機視覺的算法會對文本框的基線進行矯正,整體流程如下:

  • 對文字圖層進行檢測是否存在富文本文本框。

  • 由於在 Sketch 裏單個文本框不同樣式的文本基線一定在一條水平線上,我們的校準目標便是基於此。首先我們會對當前文本框做截圖處理。

  • 藉助 OpenCV 庫分析截圖。

  • 使用 Canny 邊緣檢測,分析出字體輪廓,確定基線位置。

  • 計算不同樣式的文本之間的基線位置差。

  • 傳回插件關於位置差的信息,插件對位置以最大字體爲基準進行矯正。

圖層再加工

智能圖層合併

設計稿的圖層和前端開發之間還有一個差異就是圖層合併的問題。往往設計師關注的焦點是能否在設計稿中實現想要的視覺效果,而不會像前端工程師一樣關注元素結構和嵌套的合理性。所以有時候在設計稿中,設計師爲了實現一個諸如 icon 或者氛圍圖等視覺效果時,會使用若干的小圖層拼接起來,但是從結構角度來講,這個拼接起來的圖形應該是一個整體,在這種情況下我們就需要合併圖層 (將若干個圖層作爲一個圖層,截圖導出)。我們實現了一套自動合併圖層的算法,算法會自動檢測一個組下是否有若干個應該被合併的圖層,然後自動在導出的過程中合併,以便後續鏈路可以處理結構。

無用圖層檢測

在設計稿中,設計師有時會添加一些對最終佈局和視覺沒有影響的圖層,爲了結構的合理性和精簡性,我們需要對這部分圖層進行篩除。如下的情況下圖層會被處理:

  • 如果有兩個 Image 圖層視覺是一樣的但是引用的 url 不同,則統一到相同的 url。

  • 如果圖層沒有 backgroundImage, backgroundColor 和 borderWidth 屬性,則圖層沒有視覺效果,直接過濾掉。

  • 如果有無某圖層沒有對圖像矩陣產生影響,則過濾掉此圖層。

  • 如果圖層被非透明圖層覆蓋,則過濾掉此圖層。

  • 如果有透明區域小於某個閾值的圖片,則過濾掉此圖層。

插件測試和度量

單元測試體系

由於 Sketch 插件是 imgcook 智能生成代碼體系的上游,在每一次代碼更改和發佈之前,需要對插件做嚴格的測試以確保功能可用,所以我們使用 Skpm-Test, 一個 Skpm 體系下的類 Jest 測試框架建立了單元測試體系,覆蓋率達到 95% 左右。

絕對定位佈局查看

如之前講到的,Sketch 插件導出的信息是包含每個子節點的絕對定位的位置和相關的 CSS 屬性,每個節點的屬性和類型和 HTML 一一映射,所以我們可以將導出 JSON 直接轉化爲 HTML + CSS 查看導出效果,使用者可以直接通過 https://imgcook.taobao.org/edit 粘貼導出的 JSON 查看效果。

視覺還原度量體系

插件視覺度量流程

我們藉助計算機視覺處理庫 OpenCV 開發了一套算法用於衡量導出的 JSON 數據是否完全還原了原設計稿的視覺效果。

OpenCV 計算視覺還原分數主要分爲以下幾個步驟:

1.圖層預處理

  • 如果原始圖像和導出圖像大小不一致,重置到相同大小。
  • 將圖像轉成灰白圖。

2.圖層對比主邏輯

分析導出的 JSON 信息,對 JSON 裏每個子元素進行如下操作:

  • 獲取子元素的寬高和位置: x, y, w, h。
  • 記錄此元素的內部有多少子元素和橫跨的元素。
  • 對於每個子元素,取出原設計稿圖相對應的區域。
  • 模版匹配:使用 OpenCV 模版匹配找出此區域在總還原圖中的位置和相似度。
  • 如果有元素跨越了此元素並且那個元素已經被處理過,則忽略此元素。
  • 如果此元素有子元素並且子元素已經被處理過,則忽略此元素。

3.處理完成導出 JSON

4.JSON 元素集合的一個數組,對於每個數組中的元素有如下屬性:

  • originPosition: 原始設計稿此元素的位置。
  • exportPosition: 導出圖層此元素的位置。
  • similarity: 導出圖層和原始設計稿相似度。
  • width: 原始寬度。
  • height: 原始高度。

可以看出,我們通過計算機視覺已經分析出了每個圖層的原始位置和還原後的位置,同時度量了每個圖層的相似度,綜合的度量分數應該綜合考慮以下三個指標:

  • 總圖層數量。
  • 還原圖層相似度。
  • 還原圖層的位置。

從這三個指標出發,我們設計如下公式計算還原度:

其中 P 表示 restore 分數,n 表示圖層的總數量,1−C𝑖 表示第 i 個還原圖層和第 i 個原始圖層的相似度, 𝛿x𝑖/𝑥 表示第 i 個還原圖層和原始圖層 x 方向位移差,x 表示總寬度,𝛿y𝑖/y 表示第 i 個還原圖層和原始圖層 y 方向位移差,y 表示總高度。使用此公式,如果全部圖層都完全沒有被還原 (相似度爲 0,x 位移爲寬度,y 位移爲高度),則 P = 0, 如果全部圖層都完美還原 (相似度爲 1, x 位移爲 0, y 位移爲 0 ),則 P = 1,所以我們可以較爲精準的度量視覺還原程度。

未來展望

去規範繼續升級

目前我們出了一些設計協議要求設計師按照一定的規範來製作設計稿,以便可以達到更好的還原效果;對設計稿的約束規範曾經高達 20+ 條,我們通過智能圖層加工層去掉了大部分規範,目前主要剩下 3 條約束,接下來,我們將進一步通過智能化的手段逐步的去掉這些對設計師和前端的約束,達到 0 約束還原。

還原能力升級

我們將在未來的 Sketch 版本中繼續提高 Sketch 插件的視覺還原度,目前階段根據度量體系 Sketch 還原的能力平均在 95% 左右,我們將在之後的版本中繼續提高這個能力。

還原效率升級

目前由於在插件中設計到大量的極速過程,導致導出速度有的時候不盡理想,我們也對這個問題進行了一定的調研,發現目前插件的確是在處理多圖層,尤其是包含多張圖片上傳的場景速度比較慢,未來我們也會對還原速度進行一次大幅度的升級。

在科技飛速發展的今天,前端智能化的浪潮已經到來,未來一些簡單的、重複性、規律性強的開發一定會逐漸地被機器取代,在這樣的過程中,機器對設計稿的理解也一定會更上一個臺階。我們也會保證插件在未來達到更高的智能化水平,從而準確地理解設計師的意圖從而更好的爲前端服務!

產品官網:https://www.imgcook.com

本文轉載自微信公衆號:Alibaba F2E

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章