web实时长图实践

背景简介
全民K歌专辑发布新玩法,传统宣传专辑战绩的流程,从获取数据,到制作海报,到传播,周期长运营成本高,如何快速分享战绩进行荣誉感的传播成为一个亟待解决的问题 。

web实时长图实践

文章插图
产品:能不能在专辑大事件触发时,自动生成一个大事件长图,供粉丝分享传播?
开发:理论上没问题,尝试下吧…
浏览器端实现方案
开发:大事件长图和专辑详情页大事件tab的视觉效果基本一致,如果能复用可以减少开发时间 。
开发:怎么复用呢?
于是便有了下面在浏览器端尝试dom转图片的两种方案:
一个在浏览器端通过JS对整个或部分页面进行“截屏”的库 。
使用方法简单,截屏的核心代码如下:
let imgBase64;html2canvas(htm,{onrendered : function(canvas){//生成base64图片数据imgBase64 = canvas.toDataURL();});
使用简单,但是坑不少,遇到的坑及解决方案:
1.截图模糊
主要解决思路:
1)将的width和属性放大为2倍 。
2)将的CSS样式width和设置为原先1倍的大小 。

2.截图不全
源码获取dom高度不准确,修改源码,获取高度后手动传,修改方式如下:
源码:
return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {if (typeof(options.onrendered) === "function") {log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");options.onrendered(canvas);}return canvas;});
修改后
//添加自定义高度宽度var width = options.width != null ? options.width : node.ownerDocument.defaultView.innerWidth;var height = options.height != null ? options.height : node.ownerDocument.defaultView.innerHeight;return renderDocument(node.ownerDocument, options, width, height, index).then(function (canvas) {if (typeof(options.onrendered) === "function") {log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");options.onrendered(canvas);}return canvas;});
3.截图慢
截图慢得从的原理说起,并不是真正的截图,而是遍历加载的页面DOM,收集所有元素的信息,然后基于从DOM读取的属性使用来绘制 。
基于这个截图原理,慢的问题优化空间不大,而且还有些CSS的限制,它只能正确地呈现它支持的CSS属性,完整的CSS属性支持列表,可以在官网查看 。
关于慢,最简单的解决方案是在用户操作前提前生成截图 。
4.crash
截图后,将图片的传到客户端的分享组件,当超过500k可能导致客户端卡死或crash,如果慢的问题还能忍,那这个问题是真的没法接受的 。
svg
除了网上也有更轻量更快的库,这些库是基于svg的,尝试了下确实比快很多 。
svg方案的尝试:
//要转成图片的domlet htm = '';let DOMURL = window.URL || window.webkitURL || window;let canvas = document.createElement('canvas');let ctx = canvas.getContext('2d');let img = new Image();let svg = new Blob([htm], {type: 'image/svg+xml;charset=utf-8'});let url = DOMURL.createObjectURL(svg);let imgBase64;img.onload = function () {ctx.drawImage(img, 0, 0);imgBase64 = canvas.toDataURL();}img.src = http://www.kingceram.com/post/url;
svg方案没法绕过的坑:
1.ios下不支持跨域图片