本篇文章主要聚焦海报图分享这个形式,探讨纯前端在H5&小程序内,合成海报到下载到本地、分享至社交平台整个流程中可能遇到的问题,以及如何解决。
绝大多数的电商平台都会设计分享裂变的功能,激励用户进行分享,这是一种拉新促活的常见措施。提到分享裂变,就免不了需要生成用户专属的分享链接或者专属海报。当然分享推广的形式多种多样,有文本链接、网页链接、图片邀请码、小程序、音视频等等。
本篇文章主要聚焦海报图分享这个形式,探讨纯前端在H5&小程序内,合成海报到下载到本地、分享至社交平台整个流程中可能遇到的问题,以及如何解决。
根据海报图生成渠道的差异,可以将海报图生成分为:客户端生成、前端生成和服务端生成,以下是从技术实现、兼容性、生成速度和功能受限四个维度进行的对比:
本篇文章着重聚焦前端H5 & 小程序内生成海报图的技术实现,如果大家对服务端、客户端生成海报图的方案感兴趣,文末有相关链接可供参考。
H5 生成海报图常推荐的方案有三种:
(1)html2canvas:基于页面中存在且可用的DOM结构、样式,构建“截图”,绘制到canvas画布中。
下面是html2canvas的技术解析,详细讲解可以参考文末链接。
(2)dom-to-image:将DOM 节点序列化为XML,包装到SVG中,再转为图片。
下面是dom-to-image的技术解析,详细讲解可以参考文末链接。
(3)canvas 纯原生绘制
以下是示例代码,这里不做赘述
html2canvas和dom-to-image都是用于在canvas的基础上封装的库,由于底层实现方式的不同,它们各有优缺点,以下是从几个维度进行的优缺点对比。
那么如何快速的确认当前的项目应该用哪个组件库呢,有没有必要逐个去验证,这里给到几点建议:
与H5类似,小程序生成海报图在项目中常用的也有三种方案:
(1)wxml-to-canvas:利用微信小程序提供的canvas组件,将指定的wxml转化成canvas绘图,然后再将其导出为图片
(2)Painter:利用JSX语法,将绘图的操作转化成绘制命令,并生成对应的canvas绘图
下图来源于Painter 2.0官方介绍
(3)Canvas/Canvas2D
以下是小程序2D Canvas 官方示例代码,详见微信小程序基础能力/画布
针对两种不同库,wxml-to-canvas更适合将已有的wxml结构转换为图片,对于复杂的定制化设计需要在wxml中拼接、排版的海报来说,并不是最佳选择。Painter则更适合在小程序中进行复杂绘制操作。
但从另一个角度看,如果对绘制性能要求比较高的业务来说,wxml-to-canvas 相比Painter更符合诉求。当然,如果仅涉及图片间的快速组合,也可以使用canvas原生绘制的能力,只是要关注图像绘制和canvas导出的实际问题。
前面两个章节,主要解决在绘制选型上的疑虑,下一步面对的就是如何解决实现过程中出现的问题。
设计还原除了关注最基础的字体样式、排版,同时也要兼顾深色模式适配、字号大小适配、页面缩放、浏览器兼容性。这些因素无疑给前端生成海报图带来巨大的压力,下面我也将从提到的这些方面进行展开,也可以作为大家选型参考或者解决方案的参考。
当业务需求涉及复杂的文本排版,那么建议直接放弃canvas原生绘制,难度大风险大耗时长。第三方库处理逻辑大同小异,本质上都是基于DOM 转为 canvas,但并不是真正的浏览器截图,都会存在一些共性问题。
如下图所示,当前设备生效的是特殊字体,那么生成海报图得到的有可能是特殊字体,出现与设计不符,不同用户生成的海报图效果不一致的情况。
如何规避这个问题呢?复制DOM并隐藏,对复制的DOM嵌入网络字体包,保证设计效果。如果是固定文案,也可以采用嵌入图片的方式。
排版常遇到的问题是文本换行、超长字符打点,通常也会叠加系统字号大小、页面缩放一起出现。
问题1: 文本换行打点怎么办?
第三方库中一般会有文本换行相关的处理:
类似html-to-canvas它的处理基于"CanvasRenderingContext2D.measureText()",在绘制时测量每个字符的宽度,进行渲染位置的更新。基于这个处理方案,超长字符打点的问题是很难解决的。
而dom-to-canvas是基于svg转图片的方式,天然的具有文本排版处理的能力,这也是这个库的优势所在。
问题2: 那如果叠加页面缩放呢?
一般h5都具有页面缩放适配的能力,复制DOM也会继承该处理,不会有太大的影响。
问题3: 如果页面有设置大字号模式,DOM在不同字号大小下展示样式有区别,但是需要导出图片样式保持一致呢?
那么就需要在复制DOM时,针对字号大小进行逆向处理,比如系统字体将字号放大1.25倍,在该场景下,复制DOM时就需要对字号进行缩小1.25倍。
深色模式适配,分为两种:
兼容性适配,与canvas和foreignObject的兼容性相关,一般来说,不建议在Android低版本中使用,性能较差。
只要使用canvas绘制图片,必然绕不过的就是跨域的问题,解决跨域问题有以下几种思路:
在请求图片时,需要增加属性 img.crossOrigin = 'anonymous' ,告知跨域服务器,本次请求可以匿名访问,不需要提供凭证。代码示例如下图所示:
设置这个就可以一劳永逸了吗,并不是,还可能出现图片缓存引起的请求跨域问题:在同一个页面中,如果canvas需要绘制的图片已经加载过了,浏览器会默认缓存下来,当canvas使用这张图片时,浏览器会直接返回缓存的图片。这时被缓存后的图片就不展示CORS请求响应头携带Access-Control-Allow-Origin的要求了,就会导致报错。
解决方案最简单的是给跨域请求追加时间戳,但这个方案会造成资源重复请求,也可能会有缓存击穿的风险。
3.2.2 ajax+Blob/base64
通过额外发一次请求,将图片转为blob或者直接用base64的图片格式,避免单张图片频繁请求。但如果涉及到的图片比较多,也会带来内存压力问题,需要注意资源及时释放。代码示例如下图所示:
不论是使用哪种方案,在小程序绘制海报图时,需要提前设定好绘制的尺寸,甚至wxml-to-canvas要求为每个元素设置固定的宽度和高度,否则会出现布局错误。所以自适应高度在小程序端是不存在的,对于排版样式就进行了初步限定。
同时,元素之间是存在层级关系的,与书写的结构强关联,这个要尤为注意。
对于元素及其样式的支持是有限的,不同库的支持程度也是不一致的,可根据业务进行选择,这里简单举例对比下:
以下是wxml-to-canvas的源码,在绘制图片时,往往是绘制网络图片,需要从远程拉取图片,转为本地临时文件存储【wx.downloadFile】,canvas绘制取临时文件地址【tempFilePath】,然后进行绘制。保存图片时再将canvas导出为临时文件【wx.canvasToTempFilePath】。
若在小程序内触发保存图片到本地【wx.saveImageToPhotosAlbum】,需要进行权限校验,这部分需要业务自行处理,如下所示。
如果选择使用Painter库绘制海报图,且为了提升性能开启了LRU存储机制,这时就要关注缓存文件的有效性,官方也在小程序 LRU 存储设计中进行了重点讲解。
研究过Painter源码的同学可能关注到在canvas导出图片的函数中,存在一个300ms的延迟,这个是为什么呢?300ms这个延迟可以去掉吗?
答案是:这个逻辑下不可以省略!否则可能出现图片缺失的问题。
Painter提供了canvas2d 接口和canvas旧接口两套逻辑,而延迟300ms出现在旧接口逻辑体系中。这是因为旧接口使用的是downloadFile将网络图片缓存到本地后再进行drawImage,而整个绘制-导出过程中没有监听图片加载完成的步骤,因此有概率出现图片未加载完成就直接绘制的情况,进而出现内容缺失。虽然加入了定时器延长时间,但不同的机器不同的图片绘制时间不同,设定单一的延迟等待并不能从根本上解决问题,反而影响生成图片的性能。
相应的,在canvas2d的体系中则可以通过 Canvas.createImage 创建图片对象,并监听图片的load事件,在回调之后执行ctx.drawImage绘制到canvas中,这样就可以有效的解决上述问题。
针对这种场景,如果有其他比较好的解决方案,欢迎读者在评论区留言。
ps: 微信官方正在推出Skyline/snapshot的截图组件,也可以实现wxml/wxss导出图片的功能,详见微信小程序Skyline /snapshot
本文主要聚焦前端生成海报图的技术选型,不同选型可能出现的问题及其解决思路。期望通过本篇文章,能够让读者在接收到相关需求时,对于一些容易踩坑的点做好前期评估。如果当前正在开发相关的需求,遇到相似的问题能够提供一些解决思路。
同时如果大家有更好的解决方案,欢迎在评论区留言。
当然,随着AI技术的发展,生成海报图可能不再需要通过代码逻辑实现。可以通过数据模型训练,更加智能化的快速生成营销海报图,那么以上的问题将不再是问题。我们也将持续关注在ToC业务中相关的实现方案,与大家一起探讨。
参考连接:
本文由哈喽比特于2月以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/Z78mMsaT5bZgPWBl3H9A0A
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。