介绍:如何利用web在移动端实现高还原富图分享?作者:闲鱼科技-袁振义背景分享是传播活动和吸引用户最重要的一环。现有的分享方式大多是用单张图片匹配主题,点击跳转到目标页面。在信息越来越多的今天,单一的话题和图片对用户的吸引力是有限的。在对推广要求较高的营销场景和裂变过程中,我们往往需要将部分页面内容作为一个整体进行分享。直接使用手机自带的截屏功能有几个问题:1)不能自定义内容格式。2)无法处理翻页情况。3)窗口区域不可控。本文通过对现有截图方案和闲鱼内部截图方案的探讨,介绍如何在移动端利用web实现高还原度的富图分享。现有方案介绍Html2Canvashtml2canvas是一个基于canvas的第三方库,在canvas上绘制DOM结构生成图片。可以将对应的DOM结构画成图片保存,方法如下。优点是简单易用,简单易用。绘制原理如下图所示。核心逻辑是克隆对应节点的DOM结构,使用parse解析成数据,构建内容绘制的canvas,返回对应的canvas。实际使用过程中,发现大概存在以下问题:不支持跨域图片。生成的图片存在跨域限制问题。绘制清晰度低。即使使用apiscale放大绘制,也会因为base64格式图片内容过长而无法传输。电弧计算精度低。因为html2canvas计算像素后绘制在canvas上,而canvas显示会被浏览器绘制,导致像素精度下降。深度节点显示为黑色。由于深度DOM结构,像素计算后,偶尔会出现像素丢失的情况。SVG简介本方案是利用svg可以包裹DOM结构的特性,将相应的target加载进去,然后将svg导出为base64格式的图片。使用方法如下。通过xmlns指定命名空间,防止多个集合下的元素和属性发生冲突。后缀中的svg和xhtml分别表示解析方式。使用不同的解析方式,实现了svg内嵌html的方式。之后通过encodeURIComponent(svg)将对应的svg转成base64即可。优点是简单易用,不依赖第三方库。实际使用过程中,发现可能存在以下问题:SVG无法连接外部资源。比如通过cdn导入的css,html中的图片链接都会被限制。不支持js执行。现在SPA页面需要先执行JS再渲染对应的DOM节点,而SVG不支持JS的执行。SVG位置和大小未定义。当遇到需要及时显示的情况时,需要实时计算位置。解决思路从上面我们可以看出,现有的两种主流的手机截屏方案都各有不足。相比之下,使用canvas绘图的方式更适合SPA应用。那么我们需要解决html2canvas对应的几个问题:图片跨域、清晰度低、弧度计算精度差、深度节点解析错误。图片跨域由newImage()生成,在image.onload阶段使用canvas绘制图片。这时候就会有跨域限制,需要通过设置crossOrigin='Anonymous'来解决。提高清晰度。绘图时发现,如果用宽度为375px的canvas导出图片,会出现图片模糊的情况。一种解决方案是提高原图的清晰度,但加载速度会大大提高,用户体验不友好。另一种方法是放大画布,通过drawImage中的参数来控制画布中的图像坐标和绘图坐标。drawImage包含几个参数:控制图片的sx、sy、sWidth、sHeight,控制绘制的画布的x、y、width、height。参数的具体含义如图所示。将方法中的宽高按比例相乘,放大图片,控制绘图坐标,就可以在画布的特定位置绘制需要的内容了。考虑到小画布的清晰度在显示阶段就足够了,只有保存阶段需要放大三倍进行绘制,采用第二种方式提高清晰度,几乎没有性能开销。下面我们来截图看看实际的效果图。下图左侧是二重结果,右图是三重结果。提高弧精度和深度DOM分析低弧精度和深度DOM分析错误本质上是由于DOM结构的复杂性。当采用通用方案进行处理时,难免无法覆盖。考虑到移动端内容有限,结构简单。决定采用特定的DOM节点针对性绘图方案来解决deepDOM解析错误的问题。好处如下:1)方法是原子的,易于维护。2)绘制高度定制化、自由组织的界面结构。3)可扩展性强。在同事胖小子的帮助下,实现了一个具体的DOM节点绘制方案。在方案构建过程中,主要存在以下难点:圆角矩形、文字自动换行。圆角矩形:通过截断的方式为特定背景绘制圆角矩形。原理是通过createPattern获取canvas上的图片内容,然后使用Path方法绘制对应的路线,使用canvas.arc绘制圆弧部分,使用canvas.lineTo绘制直线部分,截取想要的内容,并实现圆角矩形。图像内容获取。`context.createPattern(imgUrl,"no-repeat")`圆角矩形区域绘制绘制内容自动换行:思路是通过measureText获取当前文字宽度,每次加一个字,比较此时的文字宽度和线宽,超出时绘制当前行,换行,y增加行高,重复这个过程。该效果实现了一套手机截屏方法。解决现有第三方库html2canvas绘图清晰度低,弧度计算精度低,深度DOM解析错误等问题。采用原子实现方式。支持截屏自定义绘制,而不是html2canvas和svg只能多次绘制不同的DOM节点来拼凑目标的方式。总结在互联网时代,尤其是5G即将到来的今天。传统的分享模式,标题+单图,逐渐难以满足日益丰富的活动宣传需求。在流量便宜、短视频流行的今天,丰富的图文传播无疑可以传递更多的信息。目前我们已经实现了基本的DOM节点绘制方案,在站内活动中使用丰富的图文分享。相信在不久的将来,我们将能够利用移动端的截图分享功能,帮助更多的闲鱼用户高效分享内容,让用户在闲鱼中享受闲鱼,在闲鱼中畅玩。
