浅谈智能代码布局算法

原创
2022/01/07 15:58
阅读数 2.1K

前言

近些年移动互联网的普及数据爆炸式增长、算法的不断创新、算力的大幅度提高。人工智能已然逐渐渗透至各行业、各领域。智能医疗,能辅助医学诊断;智能家具。近几年,软件工程也开启了智能化的方向,也是前端领域探索研发提效新的方向,智能代码。

1. 简单了解智能代码

1.1 智能代码的目标

图 1.1.0 显而易见,智能代码的目标就是就是给定视觉稿,输出为 可靠的、可维护的、高可用 的代码。

http://img13.360buyimg.com/img/jfs/t1/210774/26/14173/146528/61cc6985Ee4fd7717/1bd86bf8dbec27f3.png

1.2 智能代码的核心能力

图 1.2.0 总结了智能代码四大核心能力。视觉稿处理能力包含布局、语义化等智能服务可二次介入编辑的可视化工作台代码生成服务。但本篇我们只探讨智能服务中的核心能力,布局算法,以及可能会涉及到的视觉稿处理。

http://img13.360buyimg.com/img/jfs/t1/155858/1/28194/110047/61cc69f2Efcc88ecb/4e5c5b51184847be.png

2. 为什么需要布局算法?

可能有小伙伴会疑惑:为什么需要布局算法,视觉稿直接处理导出来不就可以了?先不着急回答这个问题,先看看下面的例子。

http://img13.360buyimg.com/img/jfs/t1/176144/33/24275/186582/61cc68f4E18d8aeb2/0472026b838f4743.png

图 2.0.0 中,左边是视觉稿元素信息及编组信息,可以总结出这个视觉稿的编组信息:

  1. “线下狂欢 当日直达” 编组在 “小时达” 编组里
  2. “小时达” 编组的内容由 Tabs商品列表 组成
  3. “全城热爱” 编组不在 “小时达” 编组里,且视觉上 “全程热爱” 编组在 “线下狂欢 当日直达” 编组和 “小时达” 编组之间

思考一下如果按照视觉稿编组结构输出不加以处理会是怎样的情况?会不会是 图 2.0.1 的结构,显然这并不符合需求,也不够合理。

http://img13.360buyimg.com/img/jfs/t1/176275/21/24402/76784/61cc6a5bE8c7e49b9/61a88a3f6fb21cdd.png

图 2.0.2 的结果相对来说更符合我们需要的,也是更合理的。

http://img10.360buyimg.com/img/jfs/t1/173884/12/25311/76449/61cc6acfEd0369580/8fae5cfbf84bf6b7.png

从上面的例子得出的结论是显然的:不能过于信任视觉稿编组信息。

而形成此情况主要有两方面的原因:

  1. 一方面,设计师是一个视觉工种,只要视觉稿从看起来符合需求,视觉稿即已完成需求,至于用了什么技巧,如何完成,这个并不在设计师考虑范围
  2. 另外一方面,设计师不具备开发人员的布局思维,不懂得哪些应该放一起编组,哪些应该分开,而且也不能让设计师去接触开发的思维,中间的学习成本、沟通成本显然是巨大的,也不适合推广应用。

那么就产生了问题,既不能过于依赖规范去约束设计师的设计工作,又不能依赖视觉稿的编组信息,但又需把编组信息重新处理。而解决这个问题唯一办法只有引入 布局算法,将视觉稿编组去掉,所有元素相对扁平化,重组视觉稿结构。

3. 什么是布局算法?

输入一份具有 一定协议 的数据,经过一系列的算法推导,输出一份具有 描述样式结构化 的数据。这一过程就称为 布局算法。

http://img14.360buyimg.com/img/jfs/t1/218327/4/9387/121267/61cc6e95E07e49e56/944fb489b571bfd4.png

从上述可以看到,布局算法的实现需具备三个重要的要素:**数据协议、结构化、描述样式。**下面我们会对这几个要素逐一的探讨。

3.1 数据协议

在智能代码的环境里,数据协议是将视觉稿的图片、具有样式容器、文字经过一定规则处理后,用特定规则语言描述该视觉稿,而该数据可以在智能代码环境里各个子系统、子模块通行交互。

http://img20.360buyimg.com/img/jfs/t1/167741/12/26894/79925/61cc6e79E27a6ab65/63c2fe053a1fb8b5.png

下面是一份数据协议的例子:

{
 "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"
  }]
}

从上述例子,我们可以得出协议内容

  1. 描述视觉稿元素 类型 信息
  2. 描述视觉稿元素 位置坐标 信息
  3. 描述视觉稿元素 视觉信息(即样式)
  4. 描述视觉稿元素 内容 信息
  5. 其他…

3.2 结构化

可能有小伙伴会有疑问,如何理解结构化?

3.2.1 如何理解结构化?

结构化主要有两个方面:一个是元素数据间的空间关系;**另外一个是元素数据间的相互关系。**通俗理解即是 元素数据重组

3.2.1.1 元素数据间的空间关系

描述元素间的 包含、相离、相交 关系。通俗理解就是,哪些元素是某个元素子元素,哪些是兄弟元素,哪些是父元素等等。

http://img13.360buyimg.com/img/jfs/t1/220122/37/9324/126867/61cc7073E66f23233/98b52741801f22ad.png

3.2.1.2 元素数据间的相互关系

描述元素间的 性质 关系。简单可以理解就是,哪些元素可以组 成列表、哪些元素 组成行、或组成列等。

http://img13.360buyimg.com/img/jfs/t1/214872/1/9445/62868/61cc712aE62a94d33/40cfaa709ff99d43.png

3.2.2 如何结构化?

从上述自然而然就可以想到,首先可以从几个方面入手。从空间关系入手,即 空间布局;从相互关系入手,即 相互关系特征检测。当然这两个并不一定能处理所有情况,在无特征的情况下则需要借助其他手段来组成行列关系,从元素投影入手,即 **投影布局;**最后在无投影情况下最后借助 元素坐标 进行推导行列关系。

总结下来,结构化的分为大概四大手段:

  1. 空间布局
  2. 特征布局
  3. 投影布局
  4. 坐标布局

3.2.2.1 空间布局

空间布局从上述概念看,其实就是判定嵌套关系。

http://img13.360buyimg.com/img/jfs/t1/176039/33/24481/126786/61cc7331Ef65c4147/dc97e8dd436b127a.png

观察 图 3.2.2.1.0 可以看出,通过判定 相交面积 判断两个元素空间关系:

  1. 相离情况相交面积 小于等于 0
  2. 包含情况相交面积 等于 两元素其中最小的面积的元素
  3. 既不相离、又不包含,这时候则是相交,而相交面积则 大于 0,且 小于 两元素其中最小的面积的元素

空间关系也存在不少问题,下面列举比较常见的情况:

  1. 相交面积 非常小 的时候,需要根据实际情况判断是否 相离
  2. 相交面积 非常大 的时候,需要根据实际情况判断是否 包含
  3. 大部分包含情况下可以认为元素存在嵌套关系,但是也有特别的情况。观察 图 3.2.2.1.1

http://img13.360buyimg.com/img/jfs/t1/143396/36/26829/99060/61cd1c00Edaf12a8e/1a57c670b31b2e20.png

图 3.2.2.1.1 按照空间关系的判断,右图的弹出层会将左图 选择标签 包含,但实际上按照视觉稿,因为层级关系选择标签是不能被包含的。

3.2.2.2 特征布局

特征布局就是提取各个数据元素的视觉特征、内容特征,进行 相似特征聚合 判断。特征布局比较典型的就是列表,即 循环体结构。而特征要素越多,匹配越趋向精确。

http://img11.360buyimg.com/img/jfs/t1/111682/9/20503/67251/61cc6c9aE98d9f3cd/b63068ba48b57388.png

图 3.2.2.2.0 首先可以提取一些相似特征:

  1. 子项 相同高度 的容器
  2. 子项具有 图片 元素
  3. 子项具有 文字 元素
  4. 子项 图片 元素 宽高基本相同
  5. 子项 文字 元素 宽高基本相同
  6. 子项 图片 元素相对容器 坐标位置 基本一致
  7. 子项 文字 元素相对容器 坐标位置 基本一致
  8. 子项 文字 元素样式基本一致

基于这些特征,基本可以判断为列表循环体,但是并不是所有循环体都具备上面的特征,理想和现实还是具有不少差距。

有等宽不等高的;有等高不等宽的;有等宽等高的。这时候一种匹配模式显然不够用,既然一种不够,那么可以增加匹配模式,直到可以把大部分可以覆盖,并且模式间可以相互配合无冲突为止。

上面的例子其实是视觉特征,通过元素外观提取出明显的特征来进行匹配;同时也可以通过 内容特征 来进行匹配,这里就不详细举例子了。

3.2.2.3 投影布局

从数学上理解,投影是相对自身的一种 **线性变换。**为了更形象了解投影,我们从结合 光学 来认识投影。

http://img14.360buyimg.com/img/jfs/t1/142320/10/24958/47507/61cd2269E93d86882/32aa20fc089df744.png

图 3.2.2.3.0 所示,一束 垂直于水平面 的光照射在三角形上,在水平面上就产生了三角形在水平面上的 **投影,**这也是对物体本身的一种转换映射。

在上图所示中,从物体正面投影,称之为 **正向投影。**在前端中也有利用投影, **骨架图 组件,**骨架图就是基于 正向投影。既然有 正向投影,自然也有 侧投影侧向投影,则是光 平行于水平面,将影子投射到侧面,如 图 3.2.2.3.1

http://img20.360buyimg.com/img/jfs/t1/217352/33/9672/66393/61cd34bdEa6dcc87f/f5e43feee7de1815.png

在投影布局上,此两种投影我们都可以利用进行元素重组。

3.2.2.3.1 如何投影布局

正投影布局侧投影布局 思路比较相似,只是从不同视角去观察事物,最终还是利用影子的 重叠分离 进行元素重组。

下面示例对视觉稿进行正投影。 图 3.2.2.3.1.0 所示的正投影,明显可以看出,正投影的每个影子都只有一个元素,所有没必要重组。

http://img13.360buyimg.com/img/jfs/t1/140340/14/25376/90327/61cd3544Eb8e13a66/3a0e6af0c99e2f5b.png

下面示例是对视觉稿从两个方向进行侧向投影,为什么需要从两个方向进行侧投影?这个小小的问题就交给读者吧。图 3.2.2.3.1.1 所示的从上侧进行侧投影,可以观察到该视觉稿投影有三处。而其中间的影子,可以两个文字元素编组。最后出来的结构式是三列

http://img20.360buyimg.com/img/jfs/t1/95113/34/20210/85397/61cd356bEa1ab749c/c963a8f341a75795.png

下面示例是对视觉稿从两个方向进行侧向投影。图 3.2.2.3.1.2 所示的左侧进行侧投影,可以观察到该视觉稿投影只有一处,没有可编组的投影。

http://img13.360buyimg.com/img/jfs/t1/98390/34/20579/84593/61cd3592Eef2ac32a/83319eda503d430f.png

3.2.2.3.2 投影布局编组的问题

投影布局在一些情况下会遇到,左方侧投影上方侧投影 都存在有效投影情况下,就需要借助其他条件进行判断。图 3.22.3.2.0 就是上述提到的情况

http://img11.360buyimg.com/img/jfs/t1/167253/39/23199/93534/61cda3caEf2e651b4/d6aec70796a09b41.png

投影布局是个不错重组手段,但投影是基于物体外在进行布局,不能麻木信任投影,需要配个视觉稿内容信息进行辅助判断重组是否合理。

4. 样式描述

数据的样式描述,其本质就是通过已经 结构化的数据,进行对元素的 样式进行计算

大多样式其实可以通过视觉稿转换,字体大小、字体颜色、容器背景色、容器边框、以及 容器圆角 通过一定规则进行提取。但是因为视觉稿中元素都是以 绝对坐标 存在,诸如 容器内边距、外边距、行列样式 则需要通过已经结构化的数据进行计算,如 图 4.0.0 所示。

http://img13.360buyimg.com/img/jfs/t1/165074/13/24107/223473/61cdbefdE346f079e/8d9e17878343e51b.png

读者可以根据 图 4.00 思考如何计算行列布局央视,计算黄色、红色、紫色容器的外边距之类的样式。

5. 并非完美重组

理想与现实总是会存在这样那样的差距,布局算法也同样如此,重组结果并非完美,也会存在不少问题。图 5.0.0 的问题比较典型

http://img12.360buyimg.com/img/jfs/t1/106047/4/20360/342863/61cc6b86Ee65e21be/2dedf1d2ca803822.png

图 5.0.0,左边的视觉稿可以有两种的内容分割方式:第一种分割方式、右图浅蓝色部分作为内容去第二种方式、则是 Tabs 以下都作为内容区。

上面的例子很显然,这是一份具有一定交互的视觉稿,对于具有交互的视觉稿,布局算法目前还没有很好的解决办法。但话说回来,此类问题,如果没有需求文档的说明,作为开发人员,也需要思考和斟酌。

5 . 最后

希望此篇文章能够给大家对智能代码的布局算法有所基本认识。

在过去的一年,我们凹凸实验室团队已经在探索智能代码的领域,并在 6·18 大促双11 大促 业务中落地,取得不俗的成效。也坚定了智能代码方向是一个可靠、可为业务提效的方向,希望在不久将来能够做到 设计即交付

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部