|
伟大的马老师曾经说过,生产工具是生产力的决定因素之一。实际工作中,一个好用的工具确实可以有效提升开发效率。起源一次和设计同学的闲聊中,了解到他们的设计稿交付时,大多数都是基于sketch,而Psd的设计稿非常少,使得他们一身Psd技艺无用武之地。究其原因,是因为sketch对css样式支持度较高,转换到HTML元素相对容易,但Psd并无一一映射规则,且Psd的样式繁杂,解析起来相当麻烦。鲁迅先生说过:“即使艰难,也还要做;愈艰难,就愈要做”。打了一番鸡血,几位小伙伴一拍即合,便开始去做这件“艰难”的事情——将Psd设计稿转译成HTML。调研目前市面上可用的转换插件以这两种为主,具体特点分析如下:解析插件名称psd.jsag-psd解析依据psd.rb解析器photoshop官方文档star数2.5k297更新频率去年上个月issue回复速度周甚至月天级图像模式支持度深度和图像模式有限几乎所有遍历方式插件API方法自由操作原始数据颜色模式rgbargba图片操作方式转png支持canvas所有API转换css属性属性有限大量属性可转换解析数据(以6.8MB的Psd文稿为例)135KB34.1MB解析成功率重名图层会出现卡死/报错100%结果一目了然,除star数稍逊色之外,其他方面ag-psd一骑绝尘,选定插件,开始搬砖。架构设定经过设计讨论,最终决定了解析的具体步骤,如下图所示。图层分类目前图层可分为三类:组(group),文字(text),图片(image)。其中组图层有children属性,它是可以包含所有类型图层的列表;文字图层也拥有children属性,但它仅能包含文字图层。enumLayerShowType{GROUP='group',TEXT='text',IMAGE='image',}样式转换解析得到的是接近Psd源格式的数据,要想将其转换为HTML文件,首要任务是将Psd属性“翻译”成css样式。但Psd的样式无法和css样式一一对应,需要做转换映射;而且同一文本框中,可能出现多种样式文字,针对于此,需要做文字样式拆离转换映射其中,常见的opacity(透明度),borderRadius(圆角),backgroundColor(背景色)等样式是通用样式,也很容易找到对应属性,但文字就相对难处理一些。诸如删除线、下划线,加粗,倾斜等样式,Psd属性中是以Boolean形式存在;行高属性在Psd中是leading,单位是Psd文稿定义的单位;圆角在Psd中以Object存储,等等;而css样式中,是以单独样式及固定值存在,这里都需要转换映射。样式拆离如下图所示,2种不同的样式糅合在一个文本图层中,需要从图层的TextStyleRun列表中,将各自样式单独拆离出来,再做转换映射。//Psd解析原始数据"styleRuns":[{"length":1,"style":{"fontSize":24,"autoKerning":false,"fillColor":{"r":225.99885,"g":61.15665,"b":61.15665,"a":1}}},{"length":69,"style":{"fontSize":24,"autoKerning":true,"fillColor":{"r":225.99885,"g":61.15665,"b":61.15665,"a":1}}},{"length":88,"style":{"fontSize":48,"autoKerning":true,"fillColor":{"r":26.9994,"g":23.715,"b":23.715,"a":1}}},{"length":39,"style":{"fontSize":36,"autoKerning":true,"fillColor":{"r":129.999,"g":46.39215,"b":46.39215,"a":1}}}]定位处理由于Psd源数据本身就是绝对定位,最简单高效的方式是沿用它。所以我们直接使用position:absolute的样式,将图层属性top,right,bottom,left直接转换。图片处理考虑到时间及转化难度的问题,目前的图片分为两部分:设计稿中本身的图片图层及非文字图层。由于ag-psd基于canvas处理图片,此处借用canvas的toDataURL方法,将所有图片统一转换成base64格式来存储备用。HTML文件拼接准备就绪,开始拼接HTML元素。但因为场景在node端,无法直接使用Document.createElement来创建DOM,更无法直接添加css样式。几经寻找对比,终于找到一款在node端操作DOM的包——cheerio,它提供了在node端操作DOM的一套API,是jQuery的子集。有了它,何愁不能拼接完整的HTML,想到这里,不禁沾沾自喜。拼接分为如下3个步骤:1.数据解析利用上述结论,将原Psd数据进行解析转换,将图层类型转换成固定三类(组,文字,图片),同时将样式转换成对应图层类型的css属性。2.递归处理对转换后的数据进行递归处理,使用cheerio的API,对组(group)图层,新建div元素;对文字(text)图层,新建p元素;对图片(image)图层,新建img元素。再通过attr及css方法把对应的css样式添加到DOM元素中。3.单位变换本次解析是基于移动端设计稿处理,但由于移动端屏幕尺寸多种多样,px单位是无法在HTML中直接使用。考虑到大部分移动端设计稿是基于750px宽度来定义尺寸,此处均将px转换为rem单位,同时定义基准fontSize=100px。由于单位转换后,文字样式的宽度会有一定差异性,会出现折行问题。经过多次尝试,基于rem单位,我们会给文字添加一定数值的宽度补偿,最终展示的文字能够完美适配原设计稿。letnewWidth=(Math.ceil(width/10)*10*ratio+0.3)+unit;结果展示最终,我们得到了这样的结果:用户中心设计稿😄,所幸还原度还不错,粗略估计在85%以上。原设计稿:转换后页面效果(在线设计稿地址):未来规划目前Psd设计稿的还原度并非最理想状态,同时仅还原出HTML也不是我们的目的。未来有如下的规划:大幅提升设计稿的还原度完成Psd在线设计稿功能开发,方便前端开发者使用如何体验进入毕加索官网,点击右上角解析PSD按钮即可体验Psd设计稿转换。同时,也欢迎大家关注58开源项目Picasso,体验效果、改进代码、协作开发都可以提到issue中。作者介绍王明忠:天生的乐观派,而且永不止步姜娜娜:踏实做好每一件事
|
|