博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用 HTML 实现截图-html2canvas使用记录
阅读量:2431 次
发布时间:2019-05-10

本文共 5330 字,大约阅读时间需要 17 分钟。

前言

最近项目需求总是有HTML页面生成图片功能,所以就想记录一下自己在过程中遇到的问题,并加深印象,日后如果忘了也可以回顾。我们项目使用的是html2canvas插件,还有其他插件,例如dom-to-image、rasterizehtml,可以根据需求使用。

html2canvas使用问题汇总

项目中引入的是0.5.0-beta4版本的cdn链接,直接调用方法html2canvas(dom,options);第一个参数是你要绘制的dom对象,第二个参数是一些绘制的配置参数,个别参数我尝试了也没搞清楚具体什么作用可以自行看html2canvas文档,对于我用到的直接上代码:

// 生成图片        function generateImg() {            var shareContent = document.body;// 需要绘制的部分的 (原生)dom 对象 ,注意容器的宽度不要使用百分比,使用固定宽度,避免缩放问题            var width = shareContent.offsetWidth;  // 获取(原生)dom 宽度            var height = shareContent.offsetHeight;            var offsetTop = shareContent.offsetTop;  //元素距离顶部的偏移量            // var rect = shareContent.getBoundingClientRect();            var canvas = document.createElement('canvas');  //创建canvas 对象            var context = canvas.getContext('2d');            var scaleBy = 3;  //像素密度 (也可以采用自定义缩放比例)            canvas.width = width * scaleBy;   //这里 由于绘制的dom 为固定宽度,居中,所以没有偏移            canvas.height = (height + offsetTop) * scaleBy;  // 注意高度问题,由于顶部有个距离所以要加上顶部的距离,解决图像高度偏移问题            canvas.height = height * scaleBy;            // context.translate(0, -offsetTop); // 画布偏移            context.scale(scaleBy, scaleBy);            html2canvas(shareContent, {                logging: true, // 是否打印日志,默认false                taintTest: true, //检测每张图片都已经加载完成                scale: scaleBy, // 添加的scale 参数                canvas: canvas, //自定义 canvas                width: width, //dom 原始宽度                height: height, //dom 原始高度                useCORS: true, //允许跨域                onrendered: function(canvas) { // 页面绘制成功后的回调                    var url = canvas.toDataURL("image/png");                    // 生成图片后的操作                }            });        }

图片模糊解决

  • 由于像素比(DPR = 设备像素/CSS像素)的问题,电脑上截图看着还行,到手机上就会非常模糊。绘制图片时可以根据像素比把图片放大,使用时在定义图片的宽度,也可以自定义缩放比。缩放比也不是越大越好,太大了也可能会出问题。计算像素比的代码:
function getPixelRatio(context){        var backingStore = context.backingStorePixelRatio ||                context.webkitBackingStorePixelRatio ||                context.mozBackingStorePixelRatio ||                context.msBackingStorePixelRatio ||                context.oBackingStorePixelRatio ||                context.backingStorePixelRatio || 1;        return (window.devicePixelRatio || 1) / backingStore;    }
  • 绘图时尽量不要使用背景图片,直接使用img这样会更清晰

图片跨域问题

有次页面中使用了微信头像,设置了 useCORS: true 不能显示头像,设置 allowTaint:true 直接报错不能使用toDataURL可能无法导出受污染的画布;最后只有找百度了

  • 修改Nginx配置文件,由于我们项目其他地方也用到了,所以不便修改,可以修改的参考:
location ^~ /wechat_image/ {  add_header 'Access-Control-Allow-Origin' "$http_origin" always;  add_header 'Access-Control-Allow-Credentials' 'true' always;  add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;  add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;  proxy_pass http://thirdwx.qlogo.cn/;}
  • 把图片转换成base64格式并设置CrossOrigin="anonymous",尝试后有缓存的情况下还是不能正常生成图片,需要在后面拼接一个随机参数解决缓存问题,Android可以了,但ios上还是不行。
  • 后来发现直接在微信头像的img标签上设置CrossOrigin="anonymous"即 <img class="user-img" th:src="${wxUser.headImgUrl}" alt="" crossOrigin="anonymous" /> ,微信头像的请求头来就有access-control-allow-origin: *,Android和ios上都可以了,如果你之前尝试过其他方法,可能需要清下缓存,不然Android会误导你不能正常显示。
  • 最近又发现一个html2canvas的options里配置proxy为跨域的url。

生成图片替换页面时闪现问题

前面几次生成图片,都没有出现这个问题,最近一次出现了替换时页面一闪,以为是不是图片太大了,我将两个活动的图片保存对比并不是,具体我还是没搞清楚,不过通过先在dom中写一个空的img标签然后生成的src替换给img,判断图片加载完成后再将绘制的dom隐藏掉解决了这个问题。

css样式超出显示省略号消失

html2canvas不支持css样式生成省略号,百度找到了解决方法,通过js判断超过父盒子高度时用省略号替换

$(".info_text_box").each(function () {            var divH = $(this).height();            var $p = $("p", $(this)).eq(0);            while ($p.outerHeight() > divH) {                $p.html($p.html().replace(/(\s)*([a-zA-Z0-9]+|\W)(\.\.\.)?$/, "..."));            };        });

引入web字体时字体还没有显示就生成图片

window.onload=function(){} 是等页面资源加载完毕再执行,但是在ios中并不支持,后来发现当字体大小大于300px时不同字体的宽度差别很大,就通过定时器判断字体大小来判断字体是否加载成功,但最总因为字体文件加载太慢,就放弃了使用特殊字体

// 通过判断字体内容宽度判断字体加载完成function fn_fontWatch(fontFamily, cb) {        function fn_gen_span_with_font(font) {            var span=document.createElement('span');            span.style.cssText = "display:block;position:absolute;top:-9999px;left:-9999px;font-size:300px;width:auto;height:auto;line-height:normal;margin:0;padding:0;font-variant:normal;white-space:nowrap;font-family:" + font;            span.innerHTML = 'BESbswy';            document.body.append(span);            return span;        };        var span_default = fn_gen_span_with_font('serif');        var span_default_width = span_default.offsetWidth;        document.body.removeChild(span_default);        var span_font = fn_gen_span_with_font(fontFamily + ',serif');            var fn_check_loop = function() {                if(span_default_width !== span_font.offsetWidth){                    document.body.removeChild(span_font);                    cb();                } else {                    window.setTimeout(fn_check_loop,500);                }            };            fn_check_loop();    };

其他问题

  • 一次活动需要判断进入页面次序,html2canvas是通过遍历dom绘制图片的,当生成图片时除了js都会重新执行一次,导致类似刷新页面记录次序,最后次序通过ajax请求获取解决了问题;
  • html2canvas只会截取页面中可见的内容,设置了 display: none visibility:hidden 的元素是截取不到的
  • 生成图片时文字有些许变化,比如安卓的数字1就变化特别明显,而且文字的位置有点下移,原因我没找到,影响不大,目前我也没解决;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69901074/viewspace-2649899/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/69901074/viewspace-2649899/

你可能感兴趣的文章
远程办公的33种预测
查看>>
阿里巴巴架构师:十问业务中台和我的答案
查看>>
华为云发布三类六款计算实例 打造更强云端计算能力
查看>>
PHP 语言地位遭受挑战,PHP 程序员路在何方?
查看>>
PostgreSQL好评如潮,它是如何做到的?
查看>>
2017码云群英会,共享开源技术盛宴
查看>>
看完这份参会指南,Get 2017 OSC 年终盛典正确参会姿势!
查看>>
盛食厉兵 中科天玑挖掘大数据价值助力行业数字化转型
查看>>
白鹭引擎正式支持微信小游戏开发
查看>>
2018年,你所不知道的Jira!
查看>>
2017年,阿里巴巴开源的那些事
查看>>
推动边缘计算的七项核心技术
查看>>
边缘计算精华问答 | 边缘计算需要IaaS、PaaS、SaaS等服务能力吗?
查看>>
Spark精华问答 | Spark 会替代Hadoop 吗?
查看>>
豆瓣已玩烂,来爬点有逼格的 ——IMDB 电影提升你的品位
查看>>
一部刷爆朋友圈的5G短片,看完才知道5G多暖多重要!
查看>>
SDN精华问答 | SDN可以做什么?
查看>>
云评测 | 开发者最有用的开源云监控工具有哪些呢? 这7款神器总有一款适合你!...
查看>>
小团队的微服务之路
查看>>
K8S精华问答 | Kubernetes集群不能正常工作,难道是防火墙问题?
查看>>