淘宝模板代码生成器(设计稿(UI视图)自动生成代码方案的探索)

将设计草稿(UI视图)转换成代码是前端工程师每天重复的工作。这部分工作复杂度低但占用比例高,所以提高设计稿转化为代码的效率一直是前端工程师追求的方向之一。


此前,前端工程师试图将业务组件模块化成一个通用的可视化图库,通过拖拽和拼接的方式构建业务模块,实现视图重用,降低设计草稿转化为代码的R&D成本。但是随着业务的发展和个性化的驱动,通用的可视化图库已经不能覆盖所有的应用场景。提出了一种自动生成设计草图代码的方案。

1 背景

将设计草稿(UI视图)转换成代码是前端工程师每天重复的工作。这部分工作复杂度低但占用比例高,所以提高设计稿转化为代码的效率一直是前端工程师追求的方向之一。此前,前端工程师试图将业务组件模块化成一个通用的可视化图库,通过拖拽和拼接的方式构建业务模块,实现视图重用,降低设计草稿转化为代码的R&D成本。但是随着业务的发展和个性化的驱动,通用的可视化图库已经不能覆盖所有的应用场景。提出了一种自动生成设计草图代码的方案。

目前,业内主流的代码生成方案有两种,一种是通过训练神经网络,从图片或草图直接生成代码,以微软Sketch2json为代表;另一种是基于Sketch源文件,从中解析出图层信息转化成DSL并生成代码,以imgCook为代表。经过实践,我们发现第一种方案基于神经网络的代码生成算法虽然简单粗暴,但复杂层布局的准确率较低、可解释程度不高导致后续无法持续优化。方案二中Sketch源文件信息量丰富、算法自定义程度高、优化空间大。因此,我们调研了业界基于Sketch的代码自动生成方案(已对外公布或者开源),发现了一些不足并尝试解决,下面从算法准确率、代码可读性、研发流程覆盖度等方面做一下对比(该对比结果仅考察业界方案对我们自己业务的适用性,实际结果可能存在差异):目前业界主流的代码生成方案有两种。一种是通过训练神经网络直接从图片或草图生成代码,以微软Sketch2json为代表;另一种是基于草图源文件,从中解析图层信息,转换成DSL并生成代码,用imgCook表示。经过实践,我们发现第一种方案中基于神经网络的代码生成算法简单粗暴,但是复杂的图层布局准确率和可解释性较低,导致无法持续优化。第二种方案,草图源文件信息丰富,算法定制程度高,优化空区间大。因此,我们调查了业内基于草图的代码自动生成方案(已向公众发布或开源),发现了一些不足之处,并试图解决。下面就从算法准确性、代码可读性、R&D过程覆盖率等方面来做一个比较吧。(此对比结果仅考察行业方案对我们自身业务的适用性,实际结果可能有所不同):

  • 算法准确率方面:淘宝imgCook支持基于AI的组件识别,不支持成组布局,准确率中等(从官网了解到可以识别循环布局,但不能识别出测试样本中的循环布局),58 Picasso仅支持原始组件的识别,复杂组件生成错误较多,不支持成组/悬浮/循环布局,准确率较低。算法准确度:淘宝imgCook支持基于AI的组件识别,不支持分组布局,准确度中等(我们从官网了解到可以识别圆形布局,但无法识别测试样本中的圆形布局);58 Picasso只支持原组件识别,复杂组件生成错误多,不支持组/悬/圆布局,准确率低。
  • 代码可读性方面:淘宝imgCook在生成布局时,测试样本中图层重叠区域使用到了基于根布局的绝对定位方式,不符合RD预期,可读性一般,而我们的方案使用相对定位方式,可读性较好。代码可读性:淘宝imgCook生成布局时,对测试样本中的图层重叠区域使用了基于根布局的绝对定位方法,不符合RD的预期,可读性一般,而我们的方案使用了可读性较好的相对定位方法。
  • 研发流程覆盖度方面:淘宝imgCook从RD视角构建了一个IDE,支持在IDE中完成样式调整、逻辑绑定;而我们的方案从产研协作视角出发,支持数据、逻辑、埋点的可视化配置及上线。 R&D流程覆盖:淘宝imgCook从RD的角度构建了一个IDE,支持IDE中的风格调整和逻辑绑定;从产学研合作的角度,我们的方案支持数据、逻辑、埋点的可视化配置和在线。
  • 2 方案介绍

    如图所示,配置平台主要分为三大块,包括:设计草稿到视图树(UI2DSL)、视图树到代码(DSL2Code)、业务信息绑定。下面,简单介绍一下各个块的功能。

  • 将设计稿转换成DSL视图树(UI2DSL):将设计稿转换成平台无关的DSL视图树。
  • 视图树到代码(DSL2Code):基于Flex布局将DSL视图树转换为MTFlexBox静态代码。
  • 业务信息绑定:提供可视化配置工具,支持MTFlexBox静态代码绑定后台数据、业务逻辑、曝光/点击等嵌入式逻辑。
  • 2.1 设计稿转视图树(UI2DSL)

    UI2DSL主要经历以下四个步骤:

    淘宝模板代码

    2.1.1 设计稿导入

    在日常开发过程中,我们接触更多的是按钮、标题、进度条、评分组件等组件。但是草图数据源中没有这些组件,只有图层信息,图层信息是设计师在设计UI视图时使用的视图控件。组件和层之间的对应关系是一对多的。草图数据源中图层的表示如下图JSON数据结构所示,描述了图层的坐标、大小等信息。随后的布局生成基于切割层。

    [ { & # 34;class _ name & # 34:"MSTextLayer & # 34, & # 34;font _ face & # 34:"平房sc-中型& # 34;, & # 34;font _ size & # 34:13.44, & # 34;身高& # 34;:36.5, & # 34;索引& # 34;:8, & # 34;line _ height & # 34:18.24, & # 34;姓名& # 34;:"杜衡民生精选猪带骨小猪肉400g 25g & # 34, & # 34;object _ id & # 34:"ef55f 482-A690-4ec 2-8A6E-6e 7d 2c 6 a9d 91 & # 34;, & # 34;不透明度& # 34;:0.9000000357627869, & # 34;正文& # 34;:"杜衡民生精选猪带骨小猪肉400g 25g & # 34, & # 34;text _ align & # 34:"左& # 34;, & # 34;text _ color & # 34:"# FF000000 & # 34, & # 34;类型& # 34;:"正文& # 34;, & # 34;宽度& # 34;:171.8, & # 34;x & # 34:164.2, & # 34;y & # 34:726.7 }, /... 2.1.2组件识别从上面的数据来源中,我们可以看到图层的基本类型有图片、字符、矩形等。,用于组件识别。但是目前我们的进步还停留在只把图层识别为文字或者图片的阶段。后续将接入淘宝开源的pipcook框架,基于神经网络算法识别更丰富的组件类型。

    2.1.3 可视化干预

    设计稿作为输入源,是设计稿自动代码转换的基础,对设计稿的设计规格要求更高。但在实际操作中,我们发现设计人员会用Sketch中基本图形的叠加(每个图形最终在数据源中形成一层)来描述一个组件的视觉效果,因此设计稿中必然会出现冗余图层的问题,干扰DSL的生成。虽然我们尝试了用自动化的方式删除冗余图层,但对于算法无法识别的部分(比如图片上有文字图层,但图片中显示的是实际的文字,此时无法决定是否从算法层面删除文字),还是需要手动删除合并图层,否则无法正常生成DSL。设计稿主要存在以下问题。

    层未合并

    上图是从设计稿分析出来的结果。可以发现文字“美团优选”上方的图片中有很多红色的矩形框(每个矩形框都是单独的一层),算法的预期输入是一层,所以在算法处理之前需要将多个层合并成一层,右图三张图也有类似的问题。我们与设计学生进行了沟通,他们表示愿意在设计草案产生之前合并图层。然而,由于目前没有检测机制(不能自动检测层合并中是否有遗漏),层合并的问题不能完全避免。

    层位置交叉

    实践中发现,设计稿中不同字体/大小/颜色的文字排列在一起时,解析出的图层信息往往会重叠。因为DSL视图树算法是依靠位置来确定不同组件的约束关系,所以位置的交集会对算法的准确性产生很大的影响。

    复杂背景层

    上图中的红色背景是由两层(两个蓝色矩形框)拼接而成。左边的蓝色层是纯色,右边的蓝色层是渐变色。如果两层不合并,算法生成的代码就会出错。

    以上问题很难通过约束设计师来实现设计稿的标准化,所以我们提供可视化干预工具。以下是对上述问题的简要总结:

  • 问题1:未合并层的问题肉眼容易识别,用工具快速合并删除冗余层就够了。
  • 问题二:图层交叉问题肉眼难以识别,我们提供检测工具,基于这些工具可以快速修复设计稿中的交叉问题
  • 问题三:复杂背景问题肉眼难以识别,暂时没有有效的检测工具。用户可以在干预时通过生成DSL。
  • 可视化干预是UI2DSL重要的一环,经过可视化干预,将不标准的设计稿转化为标准的图层信息后再输入给算法,可以极大地提升算法的准确率。 这里我们和imgCook的处理方式有一个区别:imgCook在引入了阈值处理等算法后(更智能,出错概率更大),可视化干预能力主要体现在事后,而我们在生成DSL之前允许用户对图层进行干预,在干预时用户面对的是直观的图层信息,可以有效降低工具的使用门槛(更稳定,效果更好)。视觉干预是UI2DSL的重要组成部分。非标准的设计稿经过视觉干预后,可以转化为标准层信息,然后输入到算法中,可以大大提高算法的精度。在这里,我们的处理方式和imgCook的有一个区别:imgCook引入阈值处理等算法(更聪明,更容易出错)后,视觉干预能力主要体现在事后,而我们允许用户在生成DSL之前进行图层干预,干预时用户面对的是直观的图层信息,可以有效降低使用工具的门槛(更稳定,效果更好)。

    2.1.4 视图树生成

    人脑会如何考虑将平面数据源转换成树状DSL?首先确定整体布局结构是行布局还是列布局,然后确定局部区域应该是什么布局结构,最后组装起来形成视图树。这个过程类似于递归算法,所以我们采用递归算法作为算法的主要框架,同时引入“横纵切割+布局结构+模型评估”三个工具。

    利器1:水平和垂直切割

    在生成DSL时,采用的是整体思路,即大布局不断分割成小布局。下面让我们以动画的形式来看看简化的DSL生成过程:

    设计草图的一部分区域被视为子区域。首先,子区域与整个模板的区域一样大。根据每层的位置和大小信息,可以计算出每层的上/下/左/右边缘坐标与其他层的相对关系,找到切割点(上图中红色箭头表示的位置)。接下来,根据切割点将子区域切割成更小的子区域,如果切割过程中切割点是水平的,则生成列布局;如果切割点是垂直的,则生成一个行布局。通过连续切割子区域,获得更小的子区域,直到所有子区域都留下不可切割的层,例如图片或文本,从而可以生成完整的DSL视图树。为了方便读者理解,插图只演示了行布局和列布局的分割过程,实际情况还包括其他布局类型,要复杂得多。

    这里还要注意一个问题。当有三个切割点时,我们选择直接将子区域切割成四个子区域。其实我们只能选择一个切割点进行切割,也可以选择两个切割点进行切割。当有n个切割点时,实际上有(n +1的阶乘)种切割方法。我们将在刀具3中讨论具体选择哪种切削方法。

    工具2:布局结构

    每一层都是一个长方形。为了生成布局结构,我们只能依靠矩形的坐标信息。因此,在对布局结构进行分类时,我们根据矩形之间的位置关系(相交、分离和包含关系)进行了如下分类。

    注意:从DSL生成的结果来看,包含布局组布局的处理方式其实是一样的,都是使用类似于FrameLayout的级联布局来包含内部的层元素,但是我们还是保持分类原则(矩形之间的位置关系)不变。

    上图中,分离和包含很好理解。为什么两层相交时会出现组和悬浮两种布局结构?我们来看看上面的两组布局和悬浮布局的设计稿,分别标注了相交的元素A和B,它们在位置上的相对关系是一样的,A和B两层对应的矩形框都有相交。但是我们希望理想的DSL视图树是不同的,如下图所示:

  • 在群体布局上:A和B在逻辑上是一个整体,交叉不可避免。最后,DSL中的A和B包含在级联布局中,级联布局中没有其他元素。
  • 在浮动布局中:A和B在逻辑上不是一体的,只是碰巧交叉而已。最后,A和B在DSL中处于不同的层次。
  • 因此,当层交叉时,可能有两种布局结构,即分组布局和浮动布局。从上图可以看出,使用组布局还是浮动布局是由图层内容决定的,所以需要算法来理解图层内容,比如基于AI构建样本库,记住所有的角标签样式(如上表4所述),下次角标签相交时生成组布局。考虑到AI模型也是规则的抽象,我们先设置一套自定义的识别规则。群组布局的位置信息是有规律的,比如角标经常出现在右上角,标签经常出现在左上角,人像经常横向或纵向交叉等等。因此,我们为层与层之间的位置关系建立了一个交叉模型,如下图所示:

    上面的相交模型可以记住历史模板中分组的布局图层之间的位置关系,下次遇到相交的布局可以判断是否在历史规则库中完成识别;如果是,则按分组布局处理;否则将按悬浮布局处理。下图是历史模板构建的分组规则库。

    上面介绍了该方案中涉及的五种布局类型。目前这五种布局类型可以描述所有的模板布局,生成的代码符合RD的预期。以下是DSL设计草案的两个示例:

    工具3:模型评估

    在介绍水平切割和垂直切割时,我们可以看到,当切割点有多个时,所有切割点同时切割,但实际上算法的复杂度会更高。当有三个切割点时,实际上有五种切割方式,每种切割方式都会生成一个DSL。既然有五种切割方式,那我们应该选择哪种DSL呢?模型评估算法被用来解决这个问题。

    目前模型评价算法有两个指标:布局节点数和逆布局指标。

  • DSL中的布局节点越少,切割方式越好。
  • 逆布局指标用于评价DSL中行列布局的合理性。逆布局指数越大,越不合理。相反,反向布局指数越小,切割方法越好。
  • 下图就是一个例子。在下一个视图中查看不同切割方式下对应的模型评估方法:

    如果模型评估算法只测量布局节点的数量,那么将选择第一种切割方法生成的DSL作为最终结果。但其实第二种切割方式更合理。在第一种切割方法中,广告和即时预订是列布局,但水平对齐(横轴)不同。广告右对齐,即时预订左对齐。倒排索引表示横轴对齐不一致的节点数,通过倒排索引可以避免不合理的切割方法。

    2.1.5 列表布局

    最后一节介绍了基本的布局结构。虽然这些布局结构已经可以描述所有的UI布局,但是和RD的编码习惯还是有一些区别。

    对于上面的布局,RD通常不会把同一个条目写五遍,而是把条目放在一个类似ListView的列表组件中,这样代码看起来简洁易懂。因此,在DSL生成阶段,除了识别基本的行/列/包含/分组/浮动布局之外,还需要进一步识别行/列布局中的元素是否形成列表布局。在实验过程中,我们发现列表布局分为两种类型:单态列表组件多态列表组件。上图中每一项的布局结构都是一样的,称为单态列表组件。我们来看看多态列表组件(如下图所示)。每个项目有多个状态(选中和未选中),不同状态的布局结构不一致。

    要识别行/列布局中的单态列表组件,只需比较项目子视图树的结构。如果子视图树结构一致,则判断为单态列表组件。对于多态列表组件的识别,我们采用自动识别加人工干预的方法,比较粗糙。只要行列布局中的子项宽度/高度接近,且子项不是基本组件(基本组件容易误判),则判定为多态列表组件。具体来说,该算法计算子项的宽度和高度的标准偏差。如果小于阈值,则判断为多态列表组件,否则不是。公式如下:

    那为什么还要人工干预呢?因为是否使用列表组件实际上与产品逻辑有关,目前,我们无法识别产品文档中的逻辑。我们只能尽可能地识别所有多态列表组件,并允许用户更改生成的结果。比如上面提到的送情人的设计稿,产品可能会规定每个物品有两种状态:选中状态/未选中状态,也可能是从业务角度出发,需要突出送情人的物品。此时每一项只有一个确定的状态,这两种不同的产品逻辑在编写代码时有不同的最优技术方案。

    2.2 视图树转代码(DSL2Code)

    DSL视图树只是生成代码的中间产物,DSL代码还需要还原。DSL2Code主要包括两个步骤:属性推断和属性信息调整。

    2.2.1 属性推断

    属性推理包括两部分:风格属性和结构属性。属性包括字体、背景色、圆角等可以直接从数据源信息中获取的属性;属性包括大小、内外边距、长短轴对齐等结构信息,这些信息无法直接从数据源获得,因此结构信息的推断是这部分工作的重点。

    结构信息推理算法也是以递归算法为主要框架,通过一次递归遍历所有元素两次来完成结构信息的推理。如下图所示,递归遍历所有DSL节点时,将所有元素依次加入队列,递归完成后,将所有节点依次从队列中移除,这样所有元素一进一出遍历两次,我们称之为入队遍历和出队遍历。

    在遍历队列时,推理算法根据数据源中的信息记录每个节点的大小和位置信息,并根据位置关系计算父节点中每个子节点的期望长、短轴对齐和内外边距。当走出队列时,父节点将根据子节点的期望对齐来确定父节点的主副轴的最终对齐,并根据子节点的拉伸意图来修正父节点的大小。拉伸意味着节点的大小不是固定的,根据显示的内容,它可能在水平或垂直方向上变大或变小。比如文本节点会根据显示字数的长短而变化,甚至在字数过多的时候断行。

    2.2.2 属性信息调整

    由于输入源是基于设计稿中呈现的静态效果图,设计稿中的每个元素都缺乏真实的业务含义,同样的展示效果在不同的业务场景下会有不同的属性需求。对于这部分内容,我们无法从输入来源准确推断。为此,我们提供了可视化的属性信息调整功能来辅助代码生成。页面效果如下图所示。在此页面上,您可以查看、修改和调整DSL中所有节点的属性。

    补充完服务信息后,可以进行最终的自动代码转换,通过语法映射,DSL可以自动转换成MTFlexbox模板代码。

    3 成果展示

    以下是设计稿直接生成的代码不加修改显示后的手机截图。可以看出,取得了良好的修复效果:

    以上是我们近期对代码自动生成的探索和实践,我们将引入机器学习和神经网络算法进一步优化流程。如有其他意见或建议,请在文末评论或联系我们。

    作者简介

    田贝、邵宽、滕非等。,美团平台终端业务R&D团队R&D工程师。

    团队简介

    美团平台终端业务R&D团队的职责是在保证平台业务高效稳定迭代的同时,持续优化用户体验和R&D效率。团队负责的业务主要包括美团首页等数千万DAU高频服务,以及分享、账号、音频/视频等基础服务。,支持对接外卖、酒店等30多家业务方。通过动态能力建设,团队可以加速线上业务,帮助PM快速验证业务选择,做出业务决策;架构/服务标准化体系建设,提高前后台、平台、业务线沟通协作效率;业务监控和体验优化可以有效保障核心业务服务的成功率,同时提高用户使用美团App时的稳定性和流畅度。团队开发技术栈包括Android、iOS、React Native、Flexbox等。

    招聘信息

    美团平台终端业务R&D团队是一个充满活力的团队,对技术充满激情。现诚聘Android、iOS、FE工程师。欢迎有兴趣的同学到tech@meituan.com(注:美团平台终端业务R&D团队)投简历。

    -

    本文由美团技术团队制作,版权归美团所有。欢迎转载或使用本文内容用于分享、交流等非商业用途,请注明“内容转载自美团技术团队”。未经许可,不得复制或商业使用本文。对于任何商业活动,请发送电子邮件到tech@meituan.com申请授权。

    您可以还会对下面的文章感兴趣

    最新评论

    1. 花心少帅
      花心少帅
      发布于:2022-04-27 05:11:57 回复TA
      生成错误较多,不支持成组/悬浮/循环布局,准确率较低。算法准确度:淘宝imgCook支持基于AI的组件识别,不支持分组布局,准确度中等(我们从官网了解到可以识别圆形布局,但无法识别测试样本中的圆形布局);58 P
    1. 祝婵新茂
      祝婵新茂
      发布于:2022-04-27 01:07:23 回复TA
      冰箱是热的,草莓是苦的,昨日会回来的,你还是我的。

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    使用微信扫描二维码后

    点击右上角发送给好友