UI2Code(三)imgcook
imgcook是阿里实现的基于sketch或Ps设计稿,自动生成布局代码的工具,支持生成支持flexbox布局的代码,包括JARVIS、Vue、微信小程序、React、H5、Rax等等。由两部分组成,一个是sketch(Ps)插件,另外一部分是imgcook平台。
系列文章:
经过前面的研究,我们知道,UI2Code作为可以从UI截图生成布局代码的工作,其构建流程大致如下:
- 版面分析,包含背景分析和前景分析
- 提取GUI元素
- 组件识别
- 属性提取
- 布局推导
- DSL 推导
- 编译,得到目标平台代码
其中难点是版面分析和布局推导。
版面分析,目的是得到相对准确的背景和前景,通过传统的计算机图像计算和机器学习,将UI图片拆分并分层,得到相对独立的控件,为下一步控件识别和属性提取做准备。可以说,这部分做的好坏直接影响到后面所有的流程。
而对于线上业务逻辑来说,UI图千变万化,背景和前景可能存在很复杂的耦合关系,没有统一的规则约束,这就导致版面分析的难度较大。
- 通过纯图像计算,版面分析不准确,组件间的提取不够独立或被隔断,泛化能力不够
- 通过机器学习识别,控件属性信息不全,没有坐标、宽度等信息,且准确度不够
所以将图像计算与机器学习相结合,通过上述1、2、3、4步骤得到一定泛化能力且相对准确的版面结构和控件信息。
而对于我们来说,1、2、3、4步想要得到的内容,在Sketch设计稿里面都是有提供的,我们只需要想办法将其提取处理就可以,然后进行下一步操作。
所以经过优化后,整个流程如下:
- 提取 Sketch 设计稿信息
- 布局推导
- DSL 推导
- 编译
imgcook 做的就是这样的事情。
实际效果
页面级别 :
设计稿
运行效果
卡片级别 :
设计稿
运行效果
实现拆解
主要分为几个大的过程:
- Sketch -> Json
- Json -> DSL
- DSL -> Code
分别来看下。
sketchToJson
在sketch中选中图层,或者symbol,选中imgcook插件导出,当从sketch导出时,会产生一个json文件,以上面第二个卡片为例,信息如下
其中包含的信息包括:
artboardImg,选中symbol的渲染图,如https://ai-sample.oss-cn-hangzhou.aliyuncs.com/test/b4dd75404f6e11e9b26815c07ac4b122.png
控件唯一id
控件类型,比如Text、Image、Shape、Repeat
控件属性props,包括xy坐标、宽高、背景色、背景圆角、溢出处理(overflow)、图片内容、文字内容、字体和大小、字体颜色、行高、行数等等
children属性,这个一般都是铺平的,当时Type是Repeat时会有该值
而在插件处理过程中,可能会有以下过程:
没有图层信息,图层信息都被过滤掉
平铺的数组,没有层级关系和兄弟关系
Repeat包含多个children,内容是Text
完全被遮挡或者不可见的控件被过滤
复杂的mask计算,对于遮罩的处理
控件类型和属性都是依次解析
相当于把sketch文件中的所有信息都处理过后,得到一份期望的json文件,其中基本没有布局层次属性,仅有控件属性,包括大小、位置、控件特有属性等。
布局层次关系及位置关系由下一步来具体确定。
JsonToDSL
把上面的json复制到imgcook平台,会发起gen-layout-process请求,该请求会把json文件当做请求参数上传,并返回一个dsl的Response,请求抓包文件结果经过缩减后大概如下:
|
|
仔细观察该json文件,得出信息:
完整的DomTree,嵌套关系明确
控件属性props中多了一些信息,包括布局方式(“display”: “flex”)、flex布局方向(flexDirection)、主轴对齐方式(justifyContent)、副轴对齐方式(alignItems)、文本过长处理(text-overflow)、className、margin定位信息(marginTop、marginLeft)
语义semantic,是一个数组,最终产生一个className
组件类型componentType,包括view、text、picture
这一步完成后,基本就得到了完整可用的布局DSL。
下一步就是compile的过程。
DSL2Code
DSL compile目标代码的过程,imgcook支持比较多的代码模板,JARVIS、Vue、微信小程序、React、H5、Rax。
以Vue为例,发起请求,Response 结果这里不再列出,感兴趣的读者可以自行查看。
其中renderCode包含3部分内容:
template,DOMTree,完整的布局信息,支持动态数据绑定
script,需要绑定的方法逻辑
style,需要绑定的css样式
分别对应vue中的代码块
实际的vue代码:
|
|
从生成的代码中可以看出,div一般使用flex布局。 这里的图片也已经被上传的图床,虽然不可线上使用,但是可以即时的预览。后面可以通过插件导出到本地。
到这里生成的代码基本是可用的,并且在imgcook平台上可以调整样式,绑定方法等操作。
这里的分析是很早以前进行的,数据结构可能已经变更,但大体上应该是相同的。
实现难点
经过上面的分析,基本知道了imgcook的大致流程,个人其中的难点在如下几个方面:
一是布局推导的过程,这块也是整个UI2Code的核心内容。
从准确性和还原过程中的可选项来看,应该是通过计算得到的,其中的布局细节较多,这块也是最重要的点,其结果直接导致页面布局的好坏。
imgcook平台对于这块的实现猜测是基于切割规则加算法来实现flex布局的,整体上来说基本能够实现设计稿上所体现的布局变化,但是有时候也会显得不够灵活,下面会详细说到。
具体如何实现布局推导,可以期待imgcook官方后续有没有说明。
这里只是引用一下闲鱼之前关于切割方面的论述,基本就是先横切再竖切,递归这个过程,在切割之前可以处理坐标嵌套,得到父子信息,然后在父布局中递归切割过程,代码如下:
|
|
切割过后,根据各种优化算法得到实际的布局信息。
当然,实际生产过程肯定要比我猜测的要复杂的多得多。比如什么时候适合flex布局,什么时候适合相对布局,以及谁是优先级更高的,还有是否可以阈值控制来使相对布局变成flex布局等等。
第二个难点是ClassName的语义分析。
猜测是通过机器学习进行OCR图片识别和NLP自然语言处理翻译,这块属于易用性方面的优化。
第三个难点是配套设施,上面分析的都是如何得到一个相对准确的布局DSL,imgcook平台除了这个核心之外,平台给开发者提供了更好的拓展,根据得到的DSL信息,开发者可以根据自己的喜好编译成各种平台、各种语言。另外还有工程化配套的工具,比如导出插件,可以把生成的文件全部导出到本地,不依赖线上图床服务等等。
存在的问题
数据绑定,需要手动绑定数据,并且data名字要先想好
图床问题,默认是上传至阿里的图床,不可以直接使用,可以使用导出的zip包中包含所有的icon
界面布局,简版 flex,基本只有方向,默认margin定位
flex 的对齐方式,比如justify-content: space-between属性阈值较低,大概2个像素,不容易被触发
不过imgcook团队一直在做优化工作,相信可以做的越来越好用,造福开发者。
u51-weex
基于以上的分析,和imgcook平台的开放能力,我这边第一时间体验了自定义DSL的功能,由于我们团队内使用weex较多,所以做了一个自定义weex DSL的功能,地址在:https://github.com/imgcook-dsl/u51-weex
具体的使用方式可以参考官方文档:https://imgcook.taobao.org/docs?slug=dsl-dev
理论上来说可以对任意平台的布局进行拓展。
这块也在团队内部做了一些推广,整体上来说可以提高UI方面的开发效率,当然也存在着一些问题,这里就不具体展开了。
总结
整体来讲imgcook是一个基本可用的布局代码生成平台,对于提升工作效率方面有一些帮助。
同时,对于拓展平台支持的兼容性也比较不错。
虽然对于页面级别也可以生成,但是对于代码层级关系、后期代码维护上都不太建议直接上页面级别;比较建议的方式是生成卡片item的布局,导出作为一个component使用。
最后希望更多开发者可以使用imgcook,提出一些建议,使得他们团队可以进行更多的优化。
这篇文章写的时间比较久,当文章发布的时候发现imgcook平台又新添加了Lab,期待更多有意思的产品。
本文链接: http://w4lle.com/2019/04/08/UI2Code-2/
版权声明:本文为 w4lle 原创文章,可以随意转载,但必须在明确位置注明出处!
本文链接: http://w4lle.com/2019/04/08/UI2Code-2/