简介: 如何利用 web 实现挪动端高还原度富图文分享?
作者:闲鱼技术 - 苑振一
背景
分享是流传流动,吸引用户最重要的一环。现有分享伎俩多是题目配合单张图片,利用点击的形式跳转到指标页面。在信息越来越丰盛的明天,单个题目和图片对用户的吸引力是无限的。而在对推广要求更高的营销场景和裂变过程中,咱们往往须要将页面内容一部分作为图片整体分享进来。间接利用手机原生的截屏性能会有几个问题:1)内容格局无奈自定义。2)翻页状况无奈解决。3)视窗区域不可控。本文通过探讨现有截屏的计划和闲鱼外部截屏计划,介绍如何利用 web 实现挪动端高还原度富图文分享。
现有计划
Html2Canvas
介绍
html2canvas 是一种基于 canvas,将 DOM 构造绘制在 canvas 下面产生图片的第三方库。通过如下的形式能够将对应的 DOM 构造绘制成图片保留进去。劣势在于上手简略,使用方便。
绘制原理
原理如下图所示。外围逻辑是克隆对应节点 DOM 构造,利用 parse 解析成数据,构建 canvas 进行内容绘制,返回对应的 canvas。
理论应用过程中发现大略有如下几个问题
- 图片跨域不反对。生成的图片存在跨域限度问题。
- 绘制清晰度低 。即便应用 api
scale
放大后绘制,又会因为生成 base64 格局图片内容过长导致无奈传输。 - 圆弧计算精度低。因为 html2canvas 是计算像素后绘制到 canvas 上,而 canvas 展现又会通过浏览器绘制,导致像素精度升高。
- 深度节点呈现彩色状况。因为 DOM 构造过深,通过像素计算后,会偶然呈现像素失落状况。
SVG
介绍
该计划是利用 svg 能够包裹 DOM 构造的个性,将对应指标装载进去,之后将 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 对应的几个问题:图片跨域 , 清晰度低 , 圆弧计算精度差 , 深层节点解析 出错。
图片跨域
通过 new Image()
的形式生成图片,在 image.onload
阶段应用 canvas 绘制图片。此时会产生跨域限度,须要通过 crossOrigin = 'Anonymous'
设置来解决这个问题。
进步清晰度
在绘制中发现,如果采纳宽度 375px 的 canvas 将图片导出,会呈现图片含糊的状况。一种计划是进步原图片清晰度,然而加载速度会大大提高,用户体验不敌对。另一种形式是放大 canvas,利用 drawImage
中的参数管制图片坐标和 canvas 中的绘制坐标。drawImage
中蕴含几个参数:管制图片的 sx, sy, sWidth, sHeight 和管制 canvas 绘制的 x, y, width, height。参数具体含意如图中所示。
将办法中 width 和 height 乘上 ratio,放大图片,管制绘制坐标,就能在 canvas 特定地位上绘制出想要的内容。思考到小 canvas 在展现阶段清晰度足够,仅保留阶段须要放大三倍绘制的个性,采纳第二种办法在简直没有进步性能开销的前提下,进步清晰度。咱们以理论绘制截图来看一下成果。下图右边是一倍后果,右图是三倍后果。
圆弧精度晋升和深层 DOM 解析
圆弧精度低和深层 DOM 解析出错问题实质上还是因为 DOM 构造过于简单,当采纳通用计划解决时,不免无奈笼罩。思考到挪动端内容无限,构造简略的特点。决定采纳 特定 DOM 节点针对性绘制的计划 解决深层 DOM 解析出错的问题。益处如下:1)办法原子化,保护简略。2)绘制高度自定义化,自在组织界面构造。3)拓展性强。在共事胖仔的帮忙下实现特定 DOM 节点绘制计划。计划构建过程中次要有如下几个难点:圆角矩形 , 文字主动换行。
-
圆角矩形:通过截断的形式绘制特定背景的圆角矩形。原理是通过
createPattern
的形式在 canvas 上获取图片内容,再利用 Path 的形式,绘制对应的路线,利用canvas.arc
绘制圆弧局部,利用canvas.lineTo
绘制直线局部,截取想要的内容,实现圆角矩形。-
图片内容获取。
`context.createPattern(imgUrl, "no-repeat")`
-
圆角矩形区域绘制
![20200721115559.jpg](https://intranetproxy.alipay.com/skylark/lark/0/2020/jpeg/288128/1595303835739-f4f3bea5-562a-472a-9f45-f4599ed74997.jpeg)
-
绘制内容
![20200721115612.jpg](https://intranetproxy.alipay.com/skylark/lark/0/2020/jpeg/288128/1595303848154-c0c9fe64-b092-47c5-b82c-20d6c10c5417.jpeg)
-
- 文本主动换行:思路是通过
measureText
取得以后文本宽度,每次增加一个字,比对此时文本宽度和行宽,超过时候绘制以后行,进行换行,y 减少行高,反复这个过程。
成果
- 实现了一套挪动端截屏办法。解决了现有第三方库 html2canvas 绘制清晰度低,圆弧计算精度低,深层 DOM 解析出错的问题。
- 采纳原子化实现办法。反对截屏自定义绘制,而不是如 html2canvas 和 svg 只能通过复数次绘制不同 DOM 节点,来拼凑指标的形式。
总结
在互联网时代,尤其是 5G 马上要降临的明天。传统的分享模式,题目 + 单图片,逐步难以满足越来越丰盛的流动宣传要求。而流量的便宜化和短视频炽热的时下,富图文流传无疑能传递更多的信息。目前咱们曾经实现了根本 DOM 节点绘制计划,并在站内流动中应用富图文分享。置信在不久的未来,咱们可能利用挪动端截屏分享性能帮忙更多闲鱼用户高效率分享内容,让用户乐在闲鱼,玩在闲鱼。