当前位置: 首页 > Web前端 > HTML

网易云音乐基于C2D2C的“无损”设计合作

时间:2023-03-28 18:05:20 HTML

作者:于进以下全文根据作者在GMTC大会上的演讲整理而成,专为未能到场的小伙伴们献上~好大家下午好,今天要跟大家分享的主题是《网易云音乐基于 C2D2C 的「无损」设计协同》。和往常一样,在开始之前,我先做一个简单的自我介绍:今天分享的大纲分为4个部分,分别是:背景与问题、基于C2D2C无损设计协作的介绍、方案设计与技术挑战、总结andoutlook,backgroundandQuestion什么是(大前端)设计协作在开始之前,我们先明确一个概念:什么是(大前端)设计协作?在我的理解中,所谓(大前端)设计协作,简单来说就是在设计人员和开发人员的配合下,将产品需求转化为代码的过程。但是,在实际的设计协作中,往往会出现一些比较棘手的问题。设计协作中的问题以云音乐为例。首先,设计资产通过人肉管理,设计规范也通过人肉同步。此外,不同的设计团队有不同的设计标准,存在设计资产的重复建设。而开发作为设计的下游,会受到一个链条的影响。具体体现在:对于同一个组件,由于规格不同,导致重复开发;对于换皮等三端联动场景,开发也得反复实现三套。最后,由于开发方需要人肉还原设计稿,效率低下,容易造成开发资源瓶颈。此外,设计和研发除了各自领域的问题外,也存在相互关联的问题。具体来说:在开发之前,因为设计和开发之间存在差距,会反复关注一些边界问题和能力,沟通成本会很高;低的;开发完成后,由于开发人员长期处于时间紧、任务重的“赶工”状态,导致最终视觉还原度低,设计验收效率低。如果我们对以上问题进行分类和总结,就会发现设计协作中的问题基本上可以分为“沟通问题”??和“效率问题”,它们相互重叠,相互交叉。例如,设计资产的人性化管理会同时导致“沟通问题”??和“效率问题”。传统解决方案为解决上述问题,业界传统的做法普遍采用以设计系统为中心的“有损”设计协同。具体做法是提供两套组件库,一套用于设计的Sketch或Figma组件库,一套用于开发的React或Vue组件库。的确,“沟通”和“效率”的问题可以通过系统设计在一定程度上得到解决。但是这种做法会在无形中造成设计意图传递的损失,为什么这么说呢?这是因为,在以设计系统为中心的解决方案中,有两套独立的设计规范实现,分别对应设计资产和组件代码,且来源不同。这导致设计意图从设计人员转移到开发人员的过程中存在大量“信息损失”,而这种“损失”必须通过人际沟通来解决,这就引入了不确定性和时间成本“破坏”设计协作现在,让我们总结一下:“有损”设计协作存在三个主要问题。首先,维护成本高。因为我们需要同时维护两套组件库用于设计和开发;二是协作效率低。由于信息丢失的存在,设计和开发需要通过反复沟通消除不确定性;最后,本地效率比较低。具体表现是,设计师在打稿时,仍然需要更频繁地手动更改文案和调整布局;开发者恢复UI时,需要手动写代码,人肉恢复。我们知道,彻底解决问题的关键是找到症结所在。症结在哪里?“破坏性”设计协同问题的本质原因在于设计开发工具体系缺乏统一的协同语言。设计人员使用设计语言,而开发人员使用开发语言。它们各不相同,设计意图的传递难免会受到损失。设计协同新思路因此,要想彻底解决这个问题,最好的办法就是从工具端把设计和开发打通,统一协同语言。因此,基于这个思路,我们提出了一种基于C2D2C的无损设计协同。C2D和D2C简介首先简单介绍一下什么是C2D和D2C。所谓C2D,全称是Code2Design,就是把代码转换成设计稿。而D2C则是逆向过程,将设计稿转化为代码。“无损”设计协作的核心和无损设计协作的核心是使用C2D和D2C将协作语言与代码及其衍生产品统一起来。具体来说,设计师使用C2D将设计意图表达成设计语言。这里的设计语言不仅包括层数据,还包括层对应的组件的元数据信息,包括组件名称和组件配置参数。然后开发人员使用D2C通过使用层和组件元数据将设计语言表达为开发语言。因为完整的设计意图包含在组件元数据中,理论上这样就实现了设计意图的无损传递。“无损”设计协同的优势与有损设计协同相比,无损设计协同的优势体现在三个方面:一是维护成本低。因为在开发端只需要维护一套组件库即可。其次,协作效率相对较高。由于设计细节无损地存储在元数据中,因此无需重复确认。最后,局部效率比较高。因为设计师可以使用C2D快速生成设计稿,而开发者使用D2C可以快速还原UI。方案设计与技术挑战如何实现基于C2D2C的无损设计协同?下面详细介绍一下我们的方案设计和技术实现。产品全景下面为大家呈现的是云音乐C2D2C的产品全景。底部是设计规范。基于设计规范,我们构建了一套完整的组件体系,涵盖H5、RN、iOS、Android四大平台。在实现上,通过共享DesignToken来保证UI的一致性。所谓DesignToken可以理解为一种组件样式和代码解耦的做法:首先将控制组件样式的颜色、字号、圆角、边距等设计元素提取到变量中(即DesignToken),再通过引用DesignToken实现组件样式,既保证了三端组件UI的一致性,又能轻松实现动态换肤、品牌样式改版等“高级功能”。基于组件体系,我们构建了C2D2C工具体系,包括C2D和D2C两大关键能力,以及基于它的Sketch和Figma插件。最后,我们将D2C代码输出与低代码平台打通,最终形成了C2D2C协同流程的闭环。核心流程的整体C2D2C协同流程可以简化为下图:首先,业务设计师使用C2D插件构建业务设计稿,然后交付给业务前端开发。业务前端开发拿到设计稿后,可以使用D2C插件制作目标代码。然后D2C插件会将代码推送到低代码平台进行二次开发调整。完成后可以通过发布平台发布上线。C2D2C功能演示这里有一个一分多钟的演示视频,大家可以关注我一起来体验一下:https://crazynote.v.netease.c...首先我们设计师打开figma的C2D插件,拖动插件组件面板中的一个Tab组件,拖拽后可以选中该组件,调用配置面板进行相关配置。然后,按照同样的方法,我们拖出一个底部导航栏、一张大图卡、一张图形卡和一张文本卡。页面搭建完成后,我们就可以打开figma的D2C插件了。D2C插件有一些配置项,可以配置D2C的目标平台,页面布局等参数。然后我们把这个页面和低代码应用连接起来,最后点击生成,代码就会被推送到远程的gitlab仓库。此时,我们点击在线开发,跳转到低代码平台进行二次开发。我们可以通过构建进行二次调整,也可以直接通过源码进行二次开发,两者是可以互换的。经过刚才的演示,相信大家对C2D2C有了一个整体的认识。下面我就说说我们是怎么去实践一些比较关键的点的。跨平台插件架构由于我们设计的插件涵盖Sketch和Figma两个平台,为了降低开发成本,我们设计了跨平台的插件架构。跨平台的核心思想其实比较简单,就是用Web来承载UI和业务逻辑。我们可以把插件分为端容器和Webview,容器负责渲染和通信,Webview负责UI和业务逻辑。但这样做也存在一些挑战:首先,Sketch和Figma插件的视觉交互不一致。这主要是插件API能力的限制和配色的差异造成的。其次,Sketch和Figma插件容器与Webview的通信方式不统一,图层的渲染逻辑也不一样。那么,如何用一种架构来覆盖Sketch和Figma呢?为此,我们分层设计了插件架构,分为底层运行时、作为容器的渲染层、负责通信的协议层、业务逻辑层、负责UI展示的视图层。通过这样合理的分层,Sketch和Figma可以充分复用业务逻辑代码,也可以根据不同平台进行个性化适配。设计稿配置方案回到插件本身。前面我也提到过,我们希望插件可以帮助设计师提高效率,将他们从繁琐的文案和排版调整中解放出来。为此,我们实现了一个基于C2D的设计稿配置方案:配置的核心是动态表单+元数据绑定。从设计者的角度来看,配置行为可以分为“第一次配置”和“二次配置”。第一种配置,用户直接从插件中拖拽需要的组件,通过C2DInformation将目标组件转化为图层,同时绑定组件的配置信息,即组件的元数据到层。二次配置时,当用户点击图层时,会触发插件从图层中读取组件元数据,并使用动态表单渲染配置面板,从而实现二次配置。所以设计稿配置的核心,在于如何做C2D。C2D技术选型我们知道,C2D的本质就是将代码转化为设计稿。在业界,做C2D一般有两种方式:一种是使用Sketch或者Figma作为React的终端,使用类似RN的语法来渲染Designdraft,比如airbnb的react-sketchapp;另一种思路是直接将组件的html转成设计稿,比如ant-design的html2sketch。第一种方案需要我们为Sketch或者Figma适配一套组件库,比较优雅,但是成本高,同时也会带来后续的维护问题。第二种基于html的方案,与具体的技术栈无关,通用性强。综合考虑成本和收益后,我们最终选择了第二种方案。对于Sketch来说,由于发布时间早,C2D生态相对成熟。基于HTML的开源方案有html-sketchapp和html2sketch,但是html2sketch作为后来者在还原度上更胜一筹,所以我们选择html2sketch作为Sketch的C2D方案。Figma由于2016年发布,比较年轻,C2D生态还不够成熟。有figma-html作为基于html的开源解决方案,但是它的还原度不够好,所以我们参考了figma-html的思路,我选择了自研的html2figma。html2figma实现原理html2figma的本质其实就是DSL的转换,将描述网页UI的html转换为描述Figma设计稿的Schema。具体来说,html的元素,如div标签、p标签、svg标签,映射到figma的frame节点、text节点、vector节点。对于svg以外的常规节点,转换的过程就是将元素的CSS属性映射到节点的属性上。不管是html还是figma的Schema,由于两者对UI的描述都是完整的,理论上来说,这个属性的映射是没有问题的。我们可以举个例子来说明:比如我们有一个div元素,通过CSS,把它做成一个直径为80px,颜色为红色的圆。我们可以把它转换成一个高宽为80px,填充色为红色,圆角为40px的FigmaFrame。如您所见,转换后,两者在视觉上完全相同。但是SVG比较特殊,对SVG的分析比较复杂。SVG本身可以看作是一个独立的DSL。Figma官方可能也会考虑到这一点。为了保证SVG渲染的一致性,它提供了一个API,可以直接将SVG字符串转换为矢量图形。因此对于SVG的转换变得异常简单,无需解析,直接原封不动传给figma即可。比如这里有一个音符的图标,我们直接获取它的svg源码,然后传到figma中渲染。转换后,两者在视觉上完全相同。太简单!刚跟大家讲完C2D是怎么实现的,D2C是怎么实现的?D2C方案设计D2C的精髓提到D2C,大家首先想到的可能是阿里巴巴的imgcook,或者京东的Deco,尤其是imgcook。大家之所以熟悉它,是因为它率先实现了AI在D2C中的应用,并且取得了不错的效果。这可能会造成一种误解,认为D2C一定要用到AI,其实不然。因为D2C的本质是将设计意图还原成代码,所以D2C的关键是如何让机器理解设计意图。对于一张图片来说,由于它是非结构化的,它所包含的信息完全包含在它的二维像素平面中。对于这种场景,很适合用AI来做D2C,但是成本会很高,因为会涉及到很多标注和模型训练。如果是针对Sketch或者Figma的设计稿,因为是结构化的,转成代码是完全可行的,社区很多插件都可以做到。然而,真正的难点在于材料识别,即如何识别图层并将其与组件库关联。Metadata-basedD2C相信到这里,细心的朋友已经可以明白为什么之前做C2D的时候需要在layer中绑定metadata了?实际上,它是用于材料识别的。所以我们的D2C解决方案是基于元数据的D2C:原理并不复杂。基于C2D产生的设计稿,我们会分析设计层和元数据,同时识别素材,最后还原成代码。比如Button,C2D在生成设计稿的时候,会将组件的元数据绑定到layer,包括组件名称,组件props,API文档等,D2C时,直接读取组件元数据,转化为代码。是的,不会丢失任何设计细节。如果没有元数据怎么办?但是,对于云音乐来说,除了标准化的产品功能页面,还有一类页面场景,即云音乐特色的活动页面,创意性很强,标准化难度大。恋爱性格测试活动,钓鱼计算器活动,还有大家喜闻乐见的年报,相信大家都在朋友圈或多或少的看到过。那么如何处理这种缺少元数据的设计稿呢?我们的做法也很直接:既然你没有元数据,那我就人为添加元数据。通过协议,我们对设计稿的结构、绘图和命名进行了规范。对于设计稿的结构,我们将其标准化为页面、组件和素材三部分,各有各的功能,互不重叠。对于绘图规范,要求设计者有组件思维,将复用的UI抽象成组件或组件变体,并通过变体的参数来区分。这样做的原因是为了使最终输出的代码更具可读性和更高的质量。最后,命名规则比较简单,就三个:如果是完整的页面,在名称前加上#前缀来标识;组件名称必须遵循语义原则,不能使用特殊符号。这主要是为了方便生成元件名称代码。如果你想把一个方块显示为抠图,可以直接使用Fimga来标记。完成以上工作后,设计稿的元数据已经添加完毕,可以执行D2C了:PPT右侧是刚才钓鱼活动设计稿的D2C生成的代码:如你所见,生成的代码组件化,布局结构合理,可读性和二次开发能力强。你可能会疑惑,这么漂亮的代码是怎么生成的?下面小编就和大家一起揭秘。D2C核心流程下图是D2C的核心流程图。整体流程分为4个步骤:首先,拿到设计稿后,通过图层预处理对图层进行简化。然后,执行UI2Schema生成平台无关的中间产品。在此期间,将有一个可选的过程来优化布局。主要作用是将绝对布局转换为相对定位。然后,执行Schema2Code生成目标代码。最后进行二次开发和标准最终上线。我们来看第一步,图层预处理。图层预处理的主要目的是简化图层,降低D2C的复杂度。因为对于一个层来说,如果它包含元数据,就证明它可以被识别为一个已知的组件,它的子层就没有任何价值,可以被完全移除。因此,图层预处理可以大大降低图层分析的复杂度。层层精简后,就到了第二步——UI2Schema。UI2Schema的主要目的是将设计稿转化为平台无关的中间产品。这里的平台包括Sketch/Figma等设计平台,以及React、RN等代码平台。那么为什么要这样做呢?因为我们面对的场景比较复杂。设计端Sketch和Figma都在用,客户端React、RN、iOS、Android都需要支持。因此,通过中间层抽象后,可以实现跨设计平台、跨终端。刚才说了,在UI2Scehma中有一个可选的过程,就是layoutoptimization。虽然它是一个可选过程,但它对最终生成的代码的可读性非常关键。我们可以举个例子来说明。PPT左侧有一张设计稿,里面有ABCD四个节点。如果不优化布局,整个页面将是扁平结构,生成的代码是绝对确定的。虽然还原度可以保证,但是可读性比较差。布局优化的过程是对ABCD进行分组,先将页面分为ABC和D两行,再将ABC分为A和BC两列,最后将BC分为B和C两行。分组后,添加三个布局容器,形成嵌套的行列结构,这样最终生成的代码会更符合开发者的直觉,具有更好的可读性。不难发现,做布局优化其实就是做行列划分,那么如何实现呢?整个过程其实可以分为5个步骤。首先,我们需要获取待处理节点的坐标,然后处理节点关系:判断是包含关系、相交关系还是分离关系:如果是包含关系,则将包含的节点作为其处理子节点;howto如果是相交关系,则将两者视为一个整体,其中一个相对于整体是绝对定位的;如果分开,则不执行额外的处理。节点关系处理完成后,就是做二维空间投影,寻找行列分割的依据。例如,通过垂直投影,我们知道ABC和D属于不同的两行;通过水平投影,我们知道A和BC属于不同的两列。下一步是划分行和列。主要任务是添加布局节点,根据二维投影信息进行分组。最后是样式的计算,生成包括flex布局、绝对定位、Margin偏移量在内的样式信息。Schema生成之后,接下来要做Schema2Code,也就是多端代码的生成。值得注意的是,为了支持多端代码的生成,我们在Schema中标记的组件其实都是虚拟组件。在转换成代码的时候,我们会查询一个维护好的组件映射表,最后将它们转换成真正的组件。代码生成后,可以在本地或在线进行开发。在线开发同时支持可视化构建和源码开发,两者可以相互转换。对于iOS和Android,由于技术限制,目前只支持本地开发。这里先讨论C2D2C的技术细节,然后做一个简单的总结和展望。总结与展望目前已经打通了基于C2D2C的工作流程,关闭了协同流程。目前已经在云音乐的活动、商城、会员、音乐人四大场景落地。平均可提升设计师效率25%,研发提升33%,协同提升38%。当然,C2D2C未来在云音乐上还有很长的路要走。首先,C2D2C的能力需要不断提升,建立相应的规范和标准,作为底层能力下沉,赋能兄弟团队,帮助解锁更多平台端玩法,比如为H5/RN和本地动态下载。该平台提供编码服务。此外,C2D2C还需要接入更多基础组件以外的材料,与各事业群合作共建材料生态,让整个材料生态越来越繁荣。最后,在C2D2C核心能力、物质生态、平台端玩法三驾马车的共同作用下,无损设计协同将形成增强循环,共同放大C2D2C的价值。最后打个小广告~今年Q1我们会开源C2D2C的基石,就是云音乐开发的DolphinRN组件库。是一个高质量的RN组件库,基于TS和Hooks实现,具有强大的主题配置能力。包含50多个组件,经过100多个内部项目验证,敬请期待!最后,感谢大家的宝贵时间,谢谢!本文由网易云音乐技术团队发布。未经授权禁止任何形式的转载。我们常年招聘各种技术岗位。如果你准备换工作,又恰好喜欢云音乐,那就加入我们吧grp.music-fe(at)corp.netease.com!