百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

如何构建一个理想UI代码表达的自动化工具

toyiye 2024-06-06 22:12 12 浏览 0 评论

基于设计师产出的 Sketch,甚至是一张 PNG,就能自动生成高可维护可扩展的 UI 代码,质量堪比一位资深前端工程师, 一定是一件让整个大前端领域都为之尖叫的事情。

出于这样一个让人兴奋的命题,闲鱼团队打造了 ui-automation 工具 。

背景

如何让前端,客户端的 UI 开发更有效率,一直是一个大前端领域热门话题。

从纯手写 UI 代码,到编写 XML 表达 UI,到所见即所得的 UI 编辑器。每一步都在极大提升着大前端领域的生产效率。

当下,随着计算机视觉技术,深度学习技术在工程侧的大量使用,闲鱼团队的同学们认为,基于当前的技术,是完全能够完成接近甚至超越资深前端工程师编写的理想的 UI 表达。

问题

类比基于传统的扫描算法和最新的 pix2code 的深度学习技术。它们确实在有些场景下,生成了渲染完全一致的 UI 代码,但是往往可维护性可扩展性差,除了在简单的静态页面中能有所应用,在大部分需要动态能力的场景,无能为力。

核心的生成的 UI 代码质量问题,是之前的这些工具无法跨越的鸿沟。

而闲鱼的 ui-automation 最核心的是要解决代码质量问题,使得生成的 UI 表达是最理想的,真正解放开发同学。

ui-automation 流程

  1. 信息提取 => 2. DSL 推导 => 3. 目标平台代码

相比于渲染流程

  1. ui 代码 => 2. gpu 渲染 => 3. 画面

是一个逆向的流程。

信息提取层

  1. 基于 Skecth 信息的提取和预处理
  2. 信息全,精确,但是有冗余,干扰信息。
  3. 基于图片信息的提取
  4. 信息干净,没有冗余信息。

DSL 层

将扁平化的上游信息,树形化,同时补充了完整的布局约束的信息。

模版层

根据上游的 DSL 信息, 生成不同平台的目标代码,如 flutter,weex 等。

本文重点阐述中间层 DSL 的定义和推导过程

基础 UI 元素

我们定义了 3 中最基础的 UI 元素

Shape,Text, Image。

结构上一个基础 UI 元素有一下几部分构成:

  1. 内容
  2. 渲染样式
  3. 布局样式
  4. 布局样式沿用了经典 flexbox 的模型。

DSL 层的输入

输入中包含了上述 3 类基本的 UI 元素, 包含它们的内容,它们的渲染样式,以及相对屏幕的绝对坐标和大小,其中层级结构和布局属性在算法的推导中给出。

DSL 层的输出

输出是一个类似 dom 树的结构,有完整的布局属性,除了上述三类基础元素外,还有基础容器组件,CI 组件,BI 组件。

DSL 分层处理

在 DSL 的推导过程中, 分两大层

分组层

关注于宏观信息的处理。目标是完成一棵最佳的 ViewTree,以及扫描出足够的辅助信息给下一层属性推导使用。

(1)二元切分

对一组元素进行划分的时候

任何元素之间可能存在如下两种关系 1. 父子关系 2. 兄弟关系

根据两种关系的特点,我们使用了两个不同的模型来对数组切割(一分为二)。 1. 父子关系使用重合模型来划分。

重合模型会突出明显的若干个 background|foreground 图层 在 x,y 两个方向上都重合了剩下的所有元素。 2. 兄弟关系使用投影模型来划分。

投影模型,通过往一个方向上投影,兄弟关系的元素间 会存在明显的独立且连续分布的规律。两个方向都可投影的情况下, 优先水平方向。

在对重合模型和投影模型做适度优化后,第一次分组的容错性,稳定性,准确性得到了极大的提升。

一个简单的递归伪代码

Group(...children:View[]){}

type slice = ( views:View[] ) => View[][] //sliceByOverlaps(views) || sliceByProjection(views)

const regroup = ( views:View[] ) => views.length === 1 ? views[0] : new Group(...slice(views).map(regroup))

经过上步骤切分后, 得到的是一棵标准意义上的二叉树。

例一:

注:7 号元素是简化的处理,实际包含了 3 个基础元素。

这样的一棵二叉树。

(2) 归并

标准意义上的二叉树, 并不符合我们的需求,所以需要做一次扁平化的归并,将同方向的父子节点归并为一个数组, 降低树的深度。

一个简单的递归伪代码

经过这层处理上例一的树修正为

(3) 排序层

根据容器方向,做一轮左到右,上至下的排序。

(4) 感知辅助线

对 ViewTree 做一次深度遍历, 扫描出辅助线的信息,将影响后续的对齐方式的推导,但并不影响 ViewTree 结构。

如上图, 灰色框表示基础元素,红色框比较容器,黄色虚线表示扫描出辅助线的信息。因为有辅助线信息的存在,我们才能让第 3 行的文字,左对齐,而非右对齐。人的视觉信息处理亦是如此。

(5) 疏密切分

根据疏密分布, 在对同一容器下的孩子节点,根据疏密分布切分。

如上图,同在水平方向的兄弟节点,根据疏密关系,分解为左族群和右族群,一个向左对齐,一个向右对齐,中间的剩余空间是共享的。

(6) 扫描网格分布信息

这里用到图形相似度的算法,若干水平行, 每行的元素子树之间相似。

在垂直方向扫描得到最大不重复的组合, 打破原有层级约束重新组合。

如:

扫描后, 打破原有层级约束后, 重新组合

(7) 感知中间线

对 ViewTree 做一次深度遍历, 扫描出有效的中间线信息,会影响 ViewTree 结构。

(8) 合并层 1. 合并背景图层到容器的背景属性 2. 合并背景图层到 Text 的背景属性 3. 合并仅包含一个孩子节点的容器

大致经过上述 8 个小层的处理后, 我们得到了一个理想的 ViewTree。下一步开始我们的属性推导。

属性推导层

关注于局部信息的深度推演。

(1) 推导每一个容器的方向

推导方向是最独立的,仅仅依赖于孩子节点的分布情况。

(2) 推导每一个节点是 在流里面的,还是脱离流绝对的

这里依赖一个重合冲突算法。大体是重合冲突率高的,就是绝对的元素,重合冲突率低的是流式元素。同时存在一定的冗余能力,允许小部分的重叠(负 margin),这样极大的提高了线性布局的动态性。

(3) 推导每一个节点的大小。

以一个尽力撑满的贪心模型,推导出每一个元素的大小。同时尽力用属性约束取代直接给定宽或定高的形式,来达元素大小是到跟随内容或跟随孩子节点或跟随父容器的动态性。

对于一个容器的副轴的大小的处理,会略微复杂些,

(4) 推导出一些特殊布局

  • 网格
  • 左右对齐布局

(5) 推导主轴方向对齐方式

优先居中, 其次居左, 最后居右。

(6) 推导副轴方向对齐方式

(7) 推导位置

  • 流式元素 通过 margin 表示坐标。 居中通过(5)(6)推导的 JustifyContent,AlignItems,AlignSelf 等要素描述。
  • 绝对元素 通过 left, top, bottom, right 等描述坐标。居中通过 transform 描述。

(8) 推导 padding

ui-automation 工具目前已经运用在闲鱼内部的各个业务场景之中,伴随着大量的应用,工具本身同样日益进化。

本文作者:闲鱼技术-吉丰

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码