天天看點

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

概述

在一個常見的開發周期中往往遵循着産品需求到互動稿到設計稿再到前端開發的過程。是以在 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/design-restore

粘貼導出的 JSON 檢視效果

視覺還原度量體系

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

(插件視覺度量流程)

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

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

  • 圖層預處理
    • 如果原始圖像和導出圖像大小不一緻,重置到相同大小
    • 将圖像轉成灰白圖
  • 圖層對比主邏輯
    • 分析導出的 JSON 資訊,對 JSON 裡每個子元素進行如下操作:
    • 擷取子元素的寬高和位置: x, y, w, h
    • 記錄此元素的内部有多少子元素和橫跨的元素
    • 對于每個子元素,取出原設計稿圖相對應的區域
    • 模版比對:使用 OpenCV 模版比對找出此區域在總還原圖中的位置和相似度
    • 如果有元素跨越了此元素并且那個元素已經被處理過,則忽略此元素
    • 如果此元素有子元素并且子元素已經被處理過,則忽略此元素
  • 處理完成導出 JSON
  • JSON 元素集合的一個數組,對于每個數組中的元素有如下屬性
    • originPosition: 原始設計稿此元素的位置
    • exportPosition: 導出圖層此元素的位置
    • similarity: 導出圖層和原始設計稿相似度
    • width: 原始寬度
    • height: 原始高度

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

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

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

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

其中 P 表示 restore 分數, n 表示圖層的總數量,

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

表示第i個還原圖層和第 i 個原始圖層的相似度,

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

表示第 i 個還原圖層和原始圖層 x 方向位移差,x 表示總寬度,

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

表示第 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

歡迎加入釘釘群一起交流。

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

阿裡經濟體前端委員會前端智能化共建項目組

淘系 D2C 團隊、淘寶商家與開放團隊、UC 團隊、閑魚團隊、拍賣團隊、優酷團隊、CCO 團隊、營銷零研發全鍊路智能化業務落地團隊、淘寶設計部團隊

繼續閱讀