前言
近些年移动互联网的普及数据爆炸式增长、算法的不断创新、算力的大幅度提高。人工智能已然逐渐渗透至各行业、各领域。智能医疗,能辅助医学诊断;智能家具。近几年,软件工程也开启了智能化的方向,也是前端领域探索研发提效新的方向,智能代码。
1. 简单了解智能代码
1.1 智能代码的目标
如 图 1.1.0 显而易见,智能代码的目标就是就是给定视觉稿,输出为 可靠的、可维护的、高可用 的代码。
1.2 智能代码的核心能力
图 1.2.0 总结了智能代码四大核心能力。视觉稿处理能力;包含布局、语义化等智能服务;可二次介入编辑的可视化工作台;代码生成服务。但本篇我们只探讨智能服务中的核心能力,布局算法,以及可能会涉及到的视觉稿处理。
2. 为什么需要布局算法?
可能有小伙伴会疑惑:为什么需要布局算法,视觉稿直接处理导出来不就可以了?先不着急回答这个问题,先看看下面的例子。
在 图 2.0.0 中,左边是视觉稿元素信息及编组信息,可以总结出这个视觉稿的编组信息:
- “线下狂欢 当日直达” 编组在 “小时达” 编组里
- “小时达” 编组的内容由 Tabs 和 商品列表 组成
- “全城热爱” 编组不在 “小时达” 编组里,且视觉上 “全程热爱” 编组在 “线下狂欢 当日直达” 编组和 “小时达” 编组之间
思考一下如果按照视觉稿编组结构输出不加以处理会是怎样的情况?会不会是 图 2.0.1 的结构,显然这并不符合需求,也不够合理。
而 图 2.0.2 的结果相对来说更符合我们需要的,也是更合理的。
从上面的例子得出的结论是显然的:不能过于信任视觉稿编组信息。
而形成此情况主要有两方面的原因:
- 一方面,设计师是一个视觉工种,只要视觉稿从看起来符合需求,视觉稿即已完成需求,至于用了什么技巧,如何完成,这个并不在设计师考虑范围;
- 另外一方面,设计师不具备开发人员的布局思维,不懂得哪些应该放一起编组,哪些应该分开,而且也不能让设计师去接触开发的思维,中间的学习成本、沟通成本显然是巨大的,也不适合推广应用。
那么就产生了问题,既不能过于依赖规范去约束设计师的设计工作,又不能依赖视觉稿的编组信息,但又需把编组信息重新处理。而解决这个问题唯一办法只有引入 布局算法,将视觉稿编组去掉,所有元素相对扁平化,重组视觉稿结构。
3. 什么是布局算法?
输入一份具有 一定协议 的数据,经过一系列的算法推导,输出一份具有 描述样式、结构化 的数据。这一过程就称为 布局算法。
从上述可以看到,布局算法的实现需具备三个重要的要素:**数据协议、结构化、描述样式。**下面我们会对这几个要素逐一的探讨。
3.1 数据协议
在智能代码的环境里,数据协议是将视觉稿的图片、具有样式容器、文字经过一定规则处理后,用特定规则语言描述该视觉稿,而该数据可以在智能代码环境里各个子系统、子模块通行交互。
下面是一份数据协议的例子:
{
"id": "59C8A36E-38F6-410B-94FC-D012FE7C252C",
"type": "Block",
"props": {
"style": {},
"rect": { "x": 0, "y": 0, "width": 1543, "height": 2360 }
},
"src": "//img11.360buyimg.com/img/jfs/t1/176566/36/23819/577489/61c2edfeEb89a2f10/22a3d0d021d07b58.jpg",
"children": [{
"id": "4193849E-90F8-4949-8370-79EBED014D1C",
"type": "Text",
"props": {
"style": {
"textAlign": "left",
"color": "rgb(45, 199, 109)",
"fontWeight": 400,
"fontFamily": "MaisonNeue-Bold",
"fontSize": 12,
"letterSpacing": 0.3,
"lineHeight": 14
},
"rect": { "x": 48, "y": 23, "width": 88, "height": 14 }
},
"text": "Project meeting"
}]
}
从上述例子,我们可以得出协议内容
- 描述视觉稿元素 类型 信息
- 描述视觉稿元素 位置坐标 信息
- 描述视觉稿元素 视觉信息(即样式)
- 描述视觉稿元素 内容 信息
- 其他…
3.2 结构化
可能有小伙伴会有疑问,如何理解结构化?
3.2.1 如何理解结构化?
结构化主要有两个方面:一个是元素数据间的空间关系;**另外一个是元素数据间的相互关系。**通俗理解即是 元素数据重组。
3.2.1.1 元素数据间的空间关系
描述元素间的 包含、相离、相交 关系。通俗理解就是,哪些元素是某个元素子元素,哪些是兄弟元素,哪些是父元素等等。
3.2.1.2 元素数据间的相互关系
描述元素间的 性质 关系。简单可以理解就是,哪些元素可以组 成列表、哪些元素 组成行、或组成列等。
3.2.2 如何结构化?
从上述自然而然就可以想到,首先可以从几个方面入手。从空间关系入手,即 空间布局;从相互关系入手,即 相互关系特征检测。当然这两个并不一定能处理所有情况,在无特征的情况下则需要借助其他手段来组成行列关系,从元素投影入手,即 **投影布局;**最后在无投影情况下最后借助 元素坐标 进行推导行列关系。
总结下来,结构化的分为大概四大手段:
- 空间布局
- 特征布局
- 投影布局
- 坐标布局
3.2.2.1 空间布局
空间布局从上述概念看,其实就是判定嵌套关系。
观察 图 3.2.2.1.0 可以看出,通过判定 相交面积 判断两个元素空间关系:
- 相离情况相交面积 小于等于 0
- 包含情况相交面积 等于 两元素其中最小的面积的元素
- 既不相离、又不包含,这时候则是相交,而相交面积则 大于 0,且 小于 两元素其中最小的面积的元素
空间关系也存在不少问题,下面列举比较常见的情况:
- 相交面积 非常小 的时候,需要根据实际情况判断是否 相离
- 相交面积 非常大 的时候,需要根据实际情况判断是否 包含
- 大部分包含情况下可以认为元素存在嵌套关系,但是也有特别的情况。观察 图 3.2.2.1.1
图 3.2.2.1.1 按照空间关系的判断,右图的弹出层会将左图 选择标签 包含,但实际上按照视觉稿,因为层级关系选择标签是不能被包含的。
3.2.2.2 特征布局
特征布局就是提取各个数据元素的视觉特征、内容特征,进行 相似特征聚合 判断。特征布局比较典型的就是列表,即 循环体结构。而特征要素越多,匹配越趋向精确。
从 图 3.2.2.2.0 首先可以提取一些相似特征:
- 子项 相同高度 的容器
- 子项具有 图片 元素
- 子项具有 文字 元素
- 子项 图片 元素 宽高基本相同
- 子项 文字 元素 宽高基本相同
- 子项 图片 元素相对容器 坐标位置 基本一致
- 子项 文字 元素相对容器 坐标位置 基本一致
- 子项 文字 元素样式基本一致
基于这些特征,基本可以判断为列表循环体,但是并不是所有循环体都具备上面的特征,理想和现实还是具有不少差距。
有等宽不等高的;有等高不等宽的;有等宽等高的。这时候一种匹配模式显然不够用,既然一种不够,那么可以增加匹配模式,直到可以把大部分可以覆盖,并且模式间可以相互配合无冲突为止。
上面的例子其实是视觉特征,通过元素外观提取出明显的特征来进行匹配;同时也可以通过 内容特征 来进行匹配,这里就不详细举例子了。
3.2.2.3 投影布局
从数学上理解,投影是相对自身的一种 **线性变换。**为了更形象了解投影,我们从结合 光学 来认识投影。
如 图 3.2.2.3.0 所示,一束 垂直于水平面 的光照射在三角形上,在水平面上就产生了三角形在水平面上的 **投影,**这也是对物体本身的一种转换映射。
在上图所示中,从物体正面投影,称之为 **正向投影。**在前端中也有利用投影, **骨架图 组件,**骨架图就是基于 正向投影。既然有 正向投影,自然也有 侧投影。侧向投影,则是光 平行于水平面,将影子投射到侧面,如 图 3.2.2.3.1
在投影布局上,此两种投影我们都可以利用进行元素重组。
3.2.2.3.1 如何投影布局
正投影布局、侧投影布局 思路比较相似,只是从不同视角去观察事物,最终还是利用影子的 重叠、分离 进行元素重组。
下面示例对视觉稿进行正投影。 图 3.2.2.3.1.0 所示的正投影,明显可以看出,正投影的每个影子都只有一个元素,所有没必要重组。
下面示例是对视觉稿从两个方向进行侧向投影,为什么需要从两个方向进行侧投影?这个小小的问题就交给读者吧。图 3.2.2.3.1.1 所示的从上侧进行侧投影,可以观察到该视觉稿投影有三处。而其中间的影子,可以两个文字元素编组。最后出来的结构式是三列
下面示例是对视觉稿从两个方向进行侧向投影。图 3.2.2.3.1.2 所示的左侧进行侧投影,可以观察到该视觉稿投影只有一处,没有可编组的投影。
3.2.2.3.2 投影布局编组的问题
投影布局在一些情况下会遇到,左方侧投影 和 上方侧投影 都存在有效投影情况下,就需要借助其他条件进行判断。图 3.22.3.2.0 就是上述提到的情况
投影布局是个不错重组手段,但投影是基于物体外在进行布局,不能麻木信任投影,需要配个视觉稿内容信息进行辅助判断重组是否合理。
4. 样式描述
数据的样式描述,其本质就是通过已经 结构化的数据,进行对元素的 样式进行计算。
大多样式其实可以通过视觉稿转换,字体大小、字体颜色、容器背景色、容器边框、以及 容器圆角 通过一定规则进行提取。但是因为视觉稿中元素都是以 绝对坐标 存在,诸如 容器内边距、外边距、行列样式 则需要通过已经结构化的数据进行计算,如 图 4.0.0 所示。
读者可以根据 图 4.00 思考如何计算行列布局央视,计算黄色、红色、紫色容器的外边距之类的样式。
5. 并非完美重组
理想与现实总是会存在这样那样的差距,布局算法也同样如此,重组结果并非完美,也会存在不少问题。图 5.0.0 的问题比较典型
图 5.0.0,左边的视觉稿可以有两种的内容分割方式:第一种分割方式、右图浅蓝色部分作为内容去;第二种方式、则是 Tabs 以下都作为内容区。
上面的例子很显然,这是一份具有一定交互的视觉稿,对于具有交互的视觉稿,布局算法目前还没有很好的解决办法。但话说回来,此类问题,如果没有需求文档的说明,作为开发人员,也需要思考和斟酌。
5 . 最后
希望此篇文章能够给大家对智能代码的布局算法有所基本认识。
在过去的一年,我们凹凸实验室团队已经在探索智能代码的领域,并在 6·18 大促、双11 大促 业务中落地,取得不俗的成效。也坚定了智能代码方向是一个可靠、可为业务提效的方向,希望在不久将来能够做到 设计即交付。