作为阿里经济体前端委员会四大技术方向之一,前端智能化项目经历了 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 里蒙层的作用是相当于一个底板,所有在结构上位于其之上的图层如果区域超出了蒙层,这部分超出的区域就会被截断。对于蒙层的处理主要有以下几个不同于正常图层的点:
针对以上难点和精准还原视觉的目的,我们开发了一套算法计算 Mask 和其影响的所有图层的区域计算和形状计算,针对区域规则且形状规则的做 CSS 属性上的常规截取处理,对于无法使用 CSS 属性表示的情况对 Sketch 视觉可见的区域进行截图处理。其中,我们会进行无用图层检测,如果一个图层在它的 Mask 区域之外,则此图层将被视为无用图层被删除,同时,如果一个图层完全在它的 Mask 区域内,则此图层不会被 Mask 影响,按照原有逻辑处理。
相对于其他诸如 Shape 和 Image 图层的处理, 文字图层会更复杂一点,原因主要有:
针对第一个问题,我们对 SVG 信息进行循环检测,判断每个 SVG 子节点是否有 CSS 相关的属性发生了变化,如果有变化,就会新建立一个子节点存储相关信息。针对第二个问题,我们会对定宽的文本框导出准确的宽度信息还有行数信息,布局算法会针对此信息作出正确的判断。重点来讲一下第三个问题,由于 svg 信息在对于富文本的情况下会不准确的情况,我们设计了一套基于计算机视觉的算法会对文本框的基线进行矫正,整体流程如下:
设计稿的图层和前端开发之间还有一个差异就是图层合并的问题。往往设计师关注的焦点是能否在设计稿中实现想要的视觉效果,而不会像前端工程师一样关注元素结构和嵌套的合理性。所以有时候在设计稿中,设计师为了实现一个诸如 icon 或者氛围图等视觉效果时,会使用若干的小图层拼接起来,但是从结构角度来讲,这个拼接起来的图形应该是一个整体,在这种情况下我们就需要合并图层 (将若干个图层作为一个图层,截图导出)。我们实现了一套自动合并图层的算法,算法会自动检测一个组下是否有若干个应该被合并的图层,然后自动在导出的过程中合并,以便后续链路可以处理结构。
在设计稿中,设计师有时会添加一些对最终布局和视觉没有影响的图层,为了结构的合理性和精简性,我们需要对这部分图层进行筛除。如下的情况下图层会被处理:
由于 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 里每个子元素进行如下操作:
3.处理完成导出 JSON
4.JSON 元素集合的一个数组,对于每个数组中的元素有如下属性:
可以看出,我们通过计算机视觉已经分析出了每个图层的原始位置和还原后的位置,同时度量了每个图层的相似度,综合的度量分数应该综合考虑以下三个指标:
从这三个指标出发,我们设计如下公式计算还原度:
其中 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% 左右,我们将在之后的版本中继续提高这个能力。
目前由于在插件中设计到大量的极速过程,导致导出速度有的时候不尽理想,我们也对这个问题进行了一定的调研,发现目前插件的确是在处理多图层,尤其是包含多张图片上传的场景速度比较慢,未来我们也会对还原速度进行一次大幅度的升级。
在科技飞速发展的今天,前端智能化的浪潮已经到来,未来一些简单的、重复性、规律性强的开发一定会逐渐地被机器取代,在这样的过程中,机器对设计稿的理解也一定会更上一个台阶。我们也会保证插件在未来达到更高的智能化水平,从而准确地理解设计师的意图从而更好的为前端服务!
本文转载自微信公众号:Alibaba F2E
领取专属 10元无门槛券
私享最新 技术干货