1 背景设计稿(UI视图)转代码是前端工程师日常一直反复的工作,这部分工作复杂度较低但工作占比拟高,所以晋升设计稿转代码的效率始终是前端工程师谋求的方向之一。此前,前端工程师尝试过将业务组件模块化构建成通用视图库,并通过拖拽、拼接等模式搭建业务模块,从而实现视图复用,升高设计稿转代码的研发老本。但随着业务的倒退和个性化的驱动,通用视图库无奈笼罩所有利用场景,本文提出了一种设计稿主动生成代码的计划。
目前,业内支流的代码生成计划有两种,一种是通过训练神经网络,从图片或草图间接生成代码,以微软sketch2json为代表;另一种是基于Sketch源文件,从中解析出图层信息转化成DSL并生成代码,以imgCook为代表。通过实际,咱们发现第一种计划基于神经网络的代码生成算法尽管简略粗犷,但简单层布局的准确率较低、可解释水平不高导致后续无奈继续优化。计划二中Sketch源文件信息量丰盛、算法自定义水平高、优化空间大。因而,咱们调研了业界基于Sketch的代码主动生成计划(已对外颁布或者开源),发现了一些有余并尝试解决,上面从算法准确率、代码可读性、研发流程覆盖度等方面做一下比照(该比照后果仅考查业界计划对咱们本人业务的适用性,理论后果可能存在差别):
算法准确率方面:淘宝imgCook反对基于AI的组件辨认,不反对成组布局,准确率中等(从官网理解到能够辨认循环布局,但不能辨认出测试样本中的循环布局),58 Picasso仅反对原始组件的辨认,简单组件生成谬误较多,不反对成组/悬浮/循环布局,准确率较低。代码可读性方面:淘宝imgCook在生成布局时,测试样本中图层重叠区域应用到了基于根布局的相对定位形式,不合乎RD预期,可读性个别,而咱们的计划应用绝对定位形式,可读性较好。研发流程覆盖度方面:淘宝imgCook从RD视角构建了一个IDE,反对在IDE中实现款式调整、逻辑绑定;而咱们的计划从产研合作视角登程,反对数据、逻辑、埋点的可视化配置及上线。2 计划介绍如图所示,配置平台次要分成三块包含:设计稿转视图树(UI2DSL)、视图树转代码(DSL2Code)、以及业务信息绑定,上面简略介绍一下每一块的作用。
设计稿转DSL视图树(UI2DSL):将设计稿转化成平台无关的DSL视图树。视图树转代码(DSL2Code):将DSL视图树转化成基于Flex布局的MTFlexBox动态代码。业务信息绑定:提供可视化配置工具,反对MTFlexBox动态代码绑定后盾数据、业务逻辑、以及曝光/点击等埋点逻辑。2.1 设计稿转视图树(UI2DSL)UI2DSL次要经验以下四个步骤:
2.1.1 设计稿导入在日常开发过程中,咱们接触比拟多的组件有按钮、题目、进度条、评分组件等,然而Sketch数据源中并没有这些组件只有图层信息,图层是设计师在设计UI视图时用到的视图控件。组件与图层的对应关系是一对多的关系,图层在Sketch数据源中的表现形式如下图中的JSON数据结构所示,形容了图层的坐标、大小等信息,后续布局生成就是基于对图层的切割来实现的。
[ { "class_name":"MSTextLayer", "font_face":"PingFangSC-Medium", "font_size":13.44, "height":36.5, "index":8, "line_height":18.24, "name":"恒都民生精选猪小排带骨400g±25g", "object_id":"EF55F482-A690-4EC2-8A6E-6E7D2C6A9D91", "opacity":0.9000000357627869, "text":"恒都民生精选猪小排带骨400g±25g", "text_align":"left", "text_color":"#FF000000", "type":"text", "width":171.8, "x":164.2, "y":726.7 }, //......]2.1.2 组件辨认从下面的数据源能够看出,图层有图片、文字、矩形等根本类型,在组件辨认这一步图层须要被转化成文字/图片/进度条/评分组件/价格组件/角标等日常开发应用的组件类型。然而目前咱们的停顿还停留在只能将图层辨认为文字或者图片的阶段,后续咱们将接入淘宝开源的pipcook框架,基于神经网络算法进行更加丰盛的组件类型辨认。
2.1.3 可视化干涉设计稿作为输出源是设计稿主动转代码的根底,这对设计稿的设计规范要求较高。但在实践中,咱们发现设计师会利用Sketch中的根本图形(每个图形最终造成数据源中的一个图层)叠加来形容一个组件的视觉效果,因而设计稿中不可避免会呈现冗余图层的问题,烦扰DSL的生成。尽管咱们也尝试了利用自动化的伎俩删除冗余图层,但对于算法不能辨认的局部(例如:图片上有一个文本图层,然而理论状况中文本是显示在图片里的,这个时候无奈从算法层面决定是否删除文本),依然须要靠人工进行图层删除、合并等,否则无奈失常生成DSL。设计稿次要有以下几类问题。
图层未合并
上图是从设计稿解析进去的后果,能够发现在“美团优选”文字上方的图片中有很多红色的矩形框(每个矩形框是一个独自的图层),而算法预期的输出是一个图层,因而须要在算法解决前将多个图层合并成一个图层,右侧的三张图也有相似问题。咱们与设计同学进行过沟通,设计同学示意违心在产出设计稿之前将图层进行合并,但因为目前无奈提供检测机制(图层合并是否有脱漏无奈自动检测进去),也就无奈彻底防止图层未合并的问题。
图层地位穿插
实际中发现当设计稿中不同字体/大小/色彩的文字排列在一起时,解析进去的图层信息往往会呈现重叠的状况,因为DSL视图树算法依赖地位来确定不同组件的束缚关系,因而地位的穿插会对算法准确度造成较大的影响。
简单背景图层
上图中红色背景是由2个图层(2个蓝色矩形框)拼接造成的,左图上的蓝色图层是纯色,右图上的蓝色图层是渐变色,在两个图层未合并的状况下,算法生成的代码将会出错。
下面提出的问题,通过束缚设计师来达到设计稿的规范化,难度较大,所以咱们提供了可视化干涉工具。上面对上述问题做一个简略的总结:
问题一:图层未合并问题肉眼很容易辨认进去,利用工具将冗余图层进行疾速合并删除即可。问题二:图层穿插问题肉眼不易辨认,因而咱们提供了检测工具,基于检测工具能够对设计稿中的穿插问题疾速修复。问题三:简单背景问题肉眼不易辨认,临时也没有无效的检测工具,用户能够采纳边干涉边生成的形式生成DSL。
可视化干涉是UI2DSL重要的一环,通过可视化干涉,将不规范的设计稿转化为规范的图层信息后再输出给算法,能够极大地晋升算法的准确率。 这里咱们和imgCook的解决形式有一个区别:imgCook在引入了阈值解决等算法后(更智能,出错概率更大),可视化干涉能力次要体现在预先,而咱们在生成DSL之前容许用户对图层进行干涉,在干涉时用户面对的是直观的图层信息,能够无效升高工具的应用门槛(更稳固,成果更好)。
2.1.4 视图树生成将扁平的数据源转化为树状构造的DSL,这个过程如果是人脑来做会怎么思考呢?先确定布局的整体构造是行布局或者列布局,而后再确定部分区域应该是什么布局构造,最初组装起来造成视图树。这个过程与递归算法相似,因而咱们采纳了递归算法作为算法的主框架,同时引入了“横竖切割+布局构造+模型评估”三大利器。
利器一:横竖切割
生成DSL时采纳了整分的思路,行将大布局一直的切分成小布局,上面以动画的模式看一下简化过的DSL生成过程:
将设计稿一部分区域视为一个子区域,最开始的时候子区域和整个模板的面积一样大,基于图层的地位、大小信息,计算每个图层的上/下/左/右边缘坐标与其余图层的绝对关系,就能够寻找到切割点(如上图中红色箭头所指的地位)。接下来根据切割点,将子区域切割成更小的子区域,在切割的过程中如果切割点是横向的,则生成列布局;如果切割点是纵向的,则生成行布局。通过一直的切割子区域失去更小的子区域,直到所有的子区域只剩下图片或者文本等不可切割的图层,这样就能够生成残缺的DSL视图树了。为了不便读者了解,图例中只演示了行布局、列布局的切分过程,理论状况还蕴含了其余布局类型,会要简单许多。
这里还要留神一个问题,当有3个切割点时,咱们抉择了间接将子区域切割成4个子区域,实际上咱们能够只抉择1个切割点进行切割,也能够抉择2个切割点进行切割,当有N个切割点时,实际上存在(N的阶乘+1)种切割形式,具体抉择哪种切割形式,咱们会在利器三中探讨。
利器二:布局构造
每个图层都是一个矩形,为了生成布局构造只能依赖矩形的上下左右坐标信息。因而,对布局构造进行分类时,咱们依据矩形与矩形之间的地位关系(相交、相离和蕴含关系)做了以下分类。
留神:从生成DSL的后果来看,蕴含布局和成组布局的解决形式其实是一样的,都是应用相似于FrameLayout的层叠布局蕴含外部图层元素,然而咱们依然放弃分类准则(矩形之间的地位关系)不变。
上图中,相离、蕴含比拟好了解,为什么两个图层相交的时候,会有成组和悬浮两种类型的布局构造呢?咱们看下上述成组布局、悬浮布局两个设计稿中别离标出了相交的元素A、B,它们在地位上的绝对关系是一样的,都是A、B两个图层对应的矩形框产生了穿插。然而咱们心愿现实态的DSL视图树却有所差别,如下图所示:
成组布局中:A、B逻辑上是一个整体,穿插是必然的,最终DSL中A、B被层叠布局蕴含,层叠布局中没有其余元素。悬浮布局中:A、B逻辑上不是整体,只是碰巧穿插了,最终DSL中A、B别离在不同的层级中。
因而,对于图层相交时可能有两种类型的布局构造,别离是成组布局和悬浮布局。从上图能够看出应用成组布局还是悬浮布局是由图层内容决定的,那么就须要算法了解图层内容了,比方基于AI构建样本库,记住所有的角标款式(下面表格中4形容的),下次遇到角标相交时就生成成组布局。思考到AI模型也是对规定的形象,咱们先搭建一套自定义辨认规定。成组布局其地位信息是有法则可循的,例如:角标经常出现在右上角,标签经常出现在左上角,头像常常横向或者纵向穿插等,因而咱们针对图层之间的地位关系构建了穿插模型,如下图所示:
上图的穿插模型能够记住历史模板中成组布局图层之间的地位关系,下次遇到相交布局时判断是否在历史规定库中即可实现辨认,如果在就按成组布局解决否则依照悬浮布局解决。下图是通过历史模板构建的成组规定库。
下面介绍了本计划中波及的5种布局类型,目前来看这五种布局类型能够形容所有的模板布局,并且生成代码合乎RD的预期。上面展现两个设计稿DSL实例:
...