作者简介

by,携程高级研发经理,专注低代码平台搭建和前端智能化技术。

Jialu,携程研发总监,专注大前端技术和工程化的研究与发展。

一、 背景

在软件开发过程中,团队协作效率的提高是我们共同关注的问题。为了解决这一问题,许多团队都开始使用智能化工具。Design2Code(简称D2C)工具是其中一种广受欢迎的选择。

在本文中,我们将分享D2C工具的核心算法方案设计和实现过程,以及一系列的解决方案。无论你是开发人员,还是设计师,本文都将为你提供有价值的信息。我们希望,通过阅读本文,能帮助你更好地了解D2C工具,并在实际工作中发挥出最大的价值。

二、 前置知识

2.1 基本概念

D2C是一种通过使用智能化技术将设计稿转化为代码的工具,旨在提升开发效率,减少人力成本,并缩短设计到开发的流程。通过将设计稿源文件(如:PSD、Sketch、Figma)转化为React、Vue、小程序等平台的前端代码,再使用领域特定语言(DSL)将其转化为各端代码,D2C通常通过人工智能训练的模型或算法实现。

2.2 哪些特性

  • 高效协作:使用智能化技术,提升前端工程师和设计师之间的协作效率。

  • 高还原度:降低设计师检查页面还原度的人力成本。

  • 高兼容性:减少多端适配的开发成本。

  • 快速上线:自动生成视图层代码,减少手工工作量。

三、 业界现状

我们对业内比较出色的D2C产品进行调研,包括阿里 imgcook、京东 Deco、CodeFun、微软 AI Lab 和 Locofy。我们在调研过程中,对各家公司的产品进行了对比,但这里不再赘述。通过调研,我们得出初步结论:

  • 预装Sketch插件或上传文件解析,导出DSL数据。

  • 通过 AI 自动处理并生成前端代码,支持使用Web编辑器对代码进行人工干预和编辑。

  • 需要将设计稿数据存储在对方服务器。

  • 代码未开源,解决方案也只是简略描述。

  • 部分公司进阶功能需付费使用。

四、 效果展示

D2C系统转换流程介绍:

  • 1. 上传Sketch源文件入口 → 2. 对数据进行处理并返回结果 → 3.展示转换结果。

  • 通过“查看代码”功能获取多端代码。

  • 我们对APP、H5 、Online和小程序设计稿进行了还原比对,还原精度达到80%,且在不断提升中。

下图展示了系统转换效果:

五、 解决方案

5.1 方案分析

根据上述调研结果以及业务场景,我们的目标是将设计稿转换为代码。主要解决三个问题:

(1)提取图层信息:需要提取设计图中的图层信息,以获取所有图层元素的位置、大小、形状和颜色等信息。这些信息将为后续的页面布局提供基础。

(2)信息预处理:在将图层信息转换为代码之前,需要对信息进行一些预处理。例如,筛选和过滤无用信息和图层,处理图层style字段与css的映射关系,解决设计稿中文件夹order如何转换为布局order的问题,以及处理图片资源的导出等。预处理有助于提高后续代码生成过程中的代码质量和布局准确性。

(3)构建布局关系:利用所提取的图层信息,可以进行精确的页面布局。使页面尽可能地还原设计稿。

5.2 方案思考

为了更好的理解问题,将从简单到复杂依次讲解上述三个问题。

(1)问题1:“提取图层信息”,使用 sketch2json 开源工具可以从 Sketch 和 Figma 设计稿中提取图层信息,将矢量数据转换为 JSON 格式。数据结构中的 'layers' 对应着 HTML 的结构层,而 'style' 对应着 CSS 的表现层。下图展示了从 Sketch 中获取的数据结构。

(2)问题2:“信息预处理”,需要对基于“提取图层信息”的数据进行一系列处理。这一步的流程较为复杂,涉及到多个技术难点。我们曾经在这一步踩过许多坑,并对技术方案进行了多次调整。其中,有几个技术要点值得着重讲述,例如:

  • 筛选过滤无用信息和图层:对于 sketch2json 获取的 JSON 数据中,有因 Sketch 的映射关系存在的大量对于图像还原无效的数据字段和因为设计师对于图像绘制不规范产生的无用图层信息,所以需要对其中无效数据字段和无用图层信息做一层数据过滤,减轻 JSON 的量级方便后续计算。

  • 字段类型映射:瘦身处理后的数据还需要再精细化处理,其中 Sketch 的样式字段等与传统的 CSS 不一致,需要通过转换进行关系映射。对于 Sketch 的图层具体定义为文本还是图片等也需要做相关字段映射。

  • 图层结构重组:sketch2json 转化后的图层嵌套结构严格依赖视觉稿规范程度,可用性较低,需要对其进行一次结构重组,将所有图层打平,后续利用图层位置信息计算出准确的包含关系。

  • Order 层级深度推算:图层打平重组后,如何计算每个图层在DOM Tree中的层叠关系。我们可以根据初始JSON数据中的原始嵌套关系进行推算,为重组后的图层赋予新的层级深度值。

  • Symbol 元素处理:在 Sketch 中,Symbol 作为一种特殊元素,创建后可以被重复引用,类似前端中的组件。Symbol 元素在 Sketch 转化后的 JSON 数据中,只包含了其引用ID,它的真实图层数据被保存在了其它位置,需要通过引用ID检索到真实数据后替换 JSON数据中的 Symbol 元素。

进行系列处理之后,我们得到了前端可用的图层信息,即最终的 DSL 树形数据。

下图展示了预处理后的 DSL 数据结构:

(3)问题3:“构建布局关系”是所有步骤中最复杂的一步,因为它涉及到许多技术难点,且几乎没有可供借鉴的开源资料。我们可能需要通过不断的尝试来解决问题。实际上,构建布局关系是基于之前提到的 JSON 数据进行 absolute 和 flex 关系的规整,然后对 DSL 进行递归渲染。具体实现过程可以参阅下文的布局核心算法设计。

5.3 方案实现

5.3.1 架构设计

在进行系统架构设计时,我们综合了上述问题分析和思考后基本确定了技术的可行性和方向。为了满足系统的目标和功能,我们把系统拆分成了三个核心应用,分别负责执行核心任务。这张架构图展示了我们设计的架构,其中包括:视图渲染应用、布局算法服务和切图算法服务三个应用。在下文中,我们将对这些应用进行详细的阐述。

  • 视图渲染应用:负责渲染转换结果界面。

通过上传的Sketch文件,我们可以提取出设计稿信息并将其转换为JSON格式。这些信息将被传递给布局算法服务进行处理。算法服务将返回包含图层信息和样式信息的DSL,以树形结构形式呈现。我们将使用DSL来渲染各端页面代码。

  • 布局算法服务:负责计算元素的位置和布局,以确保界面还原精准。

具体来说,它会将设计稿的矢量数据转化为前端可用的结构化数据。这个过程包括打平和再加工等主要步骤。打平的目的是将图层之间的关系(父子和兄弟关系)重新组织,再加工的目的是过滤一些干扰图层。最终,算法服务将返回中间层的DSL数据,该数据将用于视图渲染应用的前端代码转换。

完整流程图:

  • 切图算法服务:负责将图像切割成合适的尺寸显示在界面上。

为此,我们使用一台预装了Sketch软件的Mac机器,并使用Sketchtool-cli处理设计稿中的图像、图标和路径。通过接收前端传递的图层symbolID,然后根据symbolID将设计稿中的图片导出并存储在本地磁盘中。接下来,前端会读取本地磁盘中的对应文件夹的图片,并通过接口调用的方式将图片上传到静态资源服务器。最后,服务器会返回可生产访问的CDN URL给前端,前端会将所有URL同步到DSL中。

另外如何正确合理的对图片进行切割,我们做了如下分类处理:对于sketch里的样式属性利用css不易画出时将这个图层定义为图片背景、对于多种形状结合、蒙层合并的情况,首先判断其当前图层类型、再根据特定算法判断其子图层里的元素是否满足条件进行图层之间的合并,将多个单一图片合并为一整张合理的大图、对于已经采用了三角形、椭圆等特殊形状的图层确立为图片。

完整流程图:

5.3.2 核心算法设计

(1)Sketch层级规律:

对于Sketch设计稿初始JSON数据中的树状图层结构,每两个图层的层级大小判断存在以下规则:

  • 若图层节点A是图层节点B的子孙节点,那么,图层A层级 大于 图层B层级;

  • 若两个图层节点非子孙/祖父节点,那么,这两个节点所在的最小公共子树中,若存在图层A的祖父节点为图层B的祖父节点的右兄弟节点,则表示图层A层级 大于 图层B层级。

经过分析,图层层级大小和树的先序遍历访问先后顺序一致,即根节点 < 左子树节点 < 右子树节点。

(2)投影算法:

布局关系之兄弟关系,利用光影投射的原理,通过从X轴和Y轴的方向对其中的元素进行映射,投影后所在同一个阴影块内的元素,则构成了兄弟关系。兄弟关系算法的示意图:

(3)交叉算法:

布局关系之父子关系:通过坐标计算,对于有相交关系的或包含关系的元素之间,则构成了父子关系。父子关系算法示意图:

另外在父子关系中,还需要考虑元素是否有定位。如果两个元素相交,则需要再次判断元素的大小,以决定父子关系中的父与子。为了方便后续处理布局关系,我们可以为子元素打上绝对定位的标签。

通过两个元素对角数学关系进行判断:

(4)flex布局关系推断:

处理完父子关系和兄弟关系后,为了更好地满足布局的合理性,我们需要通过算法来推测元素中的flex布局方向。

  • 通过判断子layer,当他们的大小接近,并且Y值相差在固定阈值内且X值相差过大时,可以推断出该层layer的布局使用flex,且direction为row。

  • 通过判断子layer,当他们的大小接近,并且X值相差在固定阈值内且Y值相差过大时,可以推断出该层layer的布局使用flex,且direction为column。

六、视觉约束

为了更高效、准确地还原设计稿,建议输出的 Sketch 源文件做一些规范约束:

  • 建议将组件保持在独立的画板中,这样可以避免转换无效的元素,方便工程师后续的代码逻辑开发。

  • 保留有意义的图层,删除无效的空图层,并且尽量避免过深的图层嵌套。这样可以避免渲染树过深,影响页面加载性能。

  • 图层分组(即 Sketch 中的文件夹)应该合理嵌套,避免交错放置。合理摆放元素文件夹可以有利于还原元素的 DOM 树关系。

  • 除设计上有必要以外,应尽量避免将同级元素放在容器中交错排列,因为这会导致这些元素在渲染树中被视为父子关系。

  • 对于相同类型的多行文本,建议使用一个文本图层,这样可以避免因为设计稿中的两个图层而将相同类型的文本转换为两个 HTML 段,从而提高代码复用率,减少代码重复。对于滤镜等特殊效果,建议使用图片来实现,以提高还原精度。

七、后续规划

(1)提高布局合理性:

  • 提高flex弹性布局的推算准确度

  • 提升dom tree 分割准确度

  • 减少dom tree 深度

(2)提高UI还原度:

  • 列表循环识别能力

  • 提升长页面还原度能力

(3)其它:

  • 减少视觉稿人工干预频次

  • 适配不同团队设计规范

八、总结

D2C技术是一种旨在提高企业产品研发效率,优化设计到开发流程,加速研发进度,以及辅助前端开发人员探索前端智能化道路的技术。主要优势包括:

  • 探索前端智能化:通过将设计稿转化为前端代码的方式,实现前端智能化。可以提高前端开发的效率,保证设计的精确实现。

  • 优化产品研发流程:可以提高产品研发的效率,减少人力成本,提升团队的协作效率。更高效地进行产品的迭代和优化。

  • 简化设计到开发流程:可以优化设计到开发的流程,减少沟通成本,提升工作效率。设计人员可以直接使用设计工具制作设计图,并将其转化为代码,减少设计到开发的翻译过程。

  • 加速研发进度:可以帮助团队加速研发进度,更快地将产品推向市场,并可以更快速地完成设计和开发工作。同时,也可以更快地进行产品的测试和验证。

【推荐阅读】

  • 携程机票前端Svelte生产实践

  • 携程IT数字办公平台iDesk的运营实践

  • 携程活动搭建平台的前端“开放性”建设探索

  • 秒开率70%+,携程金融SSR应用性能监测与优化

 “携程技术”公众号

  分享,交流,成长

干货 | 提升前端工程化,携程 Design2Code 从零到一的实践相关推荐

  1. 干货 | 信息图谱在携程酒店的应用

    作者简介 Kuan.Pengfei,主要从事携程酒店知识图谱.问一问智能查询助手.内容信息挖掘平台的建设运维工作,热衷于各类大数据和分布式相关技术的研究和实践. "对于用户的每一次查询,都能 ...

  2. 干货 | 深度学习在携程搜索词义解析中的应用

    作者简介 携程旅游研发部大数据与AI研发团队,为旅游事业部提供丰富的AI技术产品和技术能力. 一.背景介绍 搜索是电商最重要的门面之一,大部分用户通过搜索来找到他们想要的商品,因此搜索是用户表达意图最 ...

  3. 干货 | 携程机票 Android Jetpack 与 Kotlin Coroutines 实践

    作者简介 禹昂,携程机票移动端资深工程师,Kotlin 中文社区核心成员,图书<Kotlin 编程实践>译者. 一.前言 1.1 技术背景与选型 自 2017年 Google IO 大会以 ...

  4. 干货 | 强化学习在携程酒店推荐排序中的应用探索

    宣云儿,携程酒店排序算法工程师,主要负责酒店排序相关的算法逻辑方案设计实施.目前主要的兴趣在于排序学习.强化学习等领域的理论与应用. 前言 目前携程酒店绝大部分排序业务中所涉及的问题,基本可以通过应用 ...

  5. 干货 | 数据思维在携程商旅页面性能优化中的一次实践

    作者简介 Graviton,携程研发总监,专注数据思维驱动团队效能与技术发展. 本文旨在通过一个实际的例子,说明如何通过数据思维来解决研发工作中的一些棘手问题.通过此文,希望能够清楚地阐述我对下面几个 ...

  6. 干货 | 携程旅行App iOS工程编译优化实践

    作者简介 天超,携程资深软件工程师,关注iOS研发,喜欢用脚本语言解决各种难题. 引言 开发效率的提升,是开发者关注的一个永恒的话题.对于iOS而言,编译速度一直是影响iOS开发和集成测试效率关键的一 ...

  7. 干货 | 当你在携程搜索时,背后的推荐系统是如何工作的

    作者简介 葛荣亮,携程搜索部门高级研发工程师.2015年加入携程,目前主要负责搜索平台的前端+数据挖据工作. 一.前言 随着旅游业的发展,人们对搜索的要求越来越高.智能化大趋势下,个性化的推荐系统的应 ...

  8. 干货 | 机器学习模型在携程海外酒店推荐场景中的应用

    "关于作者:Louisa,携程算法工程师,热爱前沿算法和技术在个性化推荐和广告建模等业务的性能优化和落地. 大数据产业创新服务媒体 --聚焦数据 · 改变商业 导读 互联网企业的核心需求是& ...

  9. 干货 | 10分钟给上万客服排好班,携程大规模客服排班算法实践

    作者简介 博天,携程高级研发经理,关注大规模约束优化问题的建模和算法设计. 一.背景 客户服务部门是携程以服务质量赢得客户信赖的基石,其拥有上万名一线的客服,每天进线量巨大:且伴随着业务量的起伏,每一 ...

最新文章

  1. c++ 初始化 代码 应放在那里_Go语言goroutine调度器初始化 (12)
  2. UNIX环境高级编程第三章
  3. fckeditor 漏洞php,fckeditor上传漏洞利用总结
  4. 简单一致的Log4j2 Logger命名
  5. 【原创】StreamInsight查询系列(十九)——查询模式之检测异常
  6. Python3 学习系列 丨 博客目录索引
  7. Camera中对焦模式总结
  8. oracle blob字段索引,在oracle 数据库中使用 Blob 字段存储 一张图片并读取
  9. 1000道Python题库系列分享23(61个填空题)
  10. 【李宏毅2020 ML/DL】P10 Classification_1 | 简单的例子告诉你使用 wx+b 以及 Sigmoid 作为激活函数的合理性
  11. Http 请求处理流程[转]
  12. 笔记《深入浅出数据分析》上
  13. Java开发环境搭建实验报告
  14. 《电子商务安全》考试重点/学习重点
  15. 北京朝阳数北机房简介
  16. 17.1.1 颜色和 RGBA 值
  17. WiFiDisplay
  18. 如何利用python制作一个小游戏
  19. 问卷星禁止粘贴解决方案
  20. 群发邮件的方法有哪些?怎样大量群发邮件?

热门文章

  1. 运行python程序最常用、最重要的方法_Python面试题(4)
  2. 嵌入式毕设分享 红外热成像仪
  3. C#:用Playwright实现截长图
  4. AppStore技术支持网站
  5. springboot4S店车辆管理系统
  6. ios——扩充完善第二个demo (多练习delegate的用法)
  7. zigbee K型热电偶传感器
  8. ubuntu18 安装google谷歌浏览器
  9. 基于GDAL库图像读写——涉及(tif/tiff/bmp/jpg/png/gif等)多种格式图像的I/O
  10. Pygame小游戏:“长沙版”大富翁开局了,敢不敢约?(附多份游戏源码)