Html2canvas - 项目中遇到的那些坑点汇总(更新中...)

Posted padding1015

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Html2canvas - 项目中遇到的那些坑点汇总(更新中...)相关的知识,希望对你有一定的参考价值。

水平居中的元素截图后向左跑偏

  明明是水平居中的代码,截图出来的会偏左,结构是左图片右文字,有时候是图片自己跑到最左边,有时候是整体偏左一点点
  这个问题也不是经常遇到,场景是父div元素text-align=center;内部两个子元素设为display:inline-block的模式。然后画图就会出现左边的div偏左靠或直接在左边的情况。
  问题未解决,出现时也没研究因为啥,等有时间的时候就不出现了。。。

靠背景图露脸的dom们会有底线
  截图时,如果有一个dom元素是用背景图填充的,里边没有任何结构,那么截图出来的底部会有一条和背景图底部一致的一条线
  有时候靠拉伸dom元素的高度解决了,有时候又不行。

the operation is insecure
  canvas.toDataURL 报错 the operation is insecure
  canvas.toDataURL(type, encoderOptions);语法
  配置如:canvas.toDataURL("image/png", 0.7);
  参数type指定图片类型,如果指定的类型不被支持则以默认值image/png替代;
  encoderOptions(第二个参数)可以为image/jpeg或image/webp类型的图片设置图片质量,取值0-1,超出则以默认值0.92替代。


html2canvas在微信中base64码为空
  在微信中或者可以说在移动端浏览器里,canvas.toDataURL不成功。canvas.toDataURL(type) 得到空的 data:;
  折腾了半天。。。
  同事说如果base64码的长度有个限制,忘了超过多少就不行了,后来我尝试把放大四倍改成放大两倍,问题竟然解决了!!
  不要笑话我放大了四倍,为了清晰哈哈哈。但是改成两倍后和四倍比也没差。反倒是挖了个坑自己填了半天!

不可见的元素截图后是空白
  没法截图看不见的,比如opacity为0的东西,或者visibility为hidden的,更别说display:none了。都不行,
  截出来的一样是白色的,可想而知,毕竟没截上东西当然就是白色了。
  解决方法是让canvas部分隐藏到后边。最终选择方案,层级设为-1,上一层的把他盖住。

  前提是上一层要又一个可以设置的背景色,能把他盖住不被世人看到

html2canvas结合微信里的长按存图功能
  先用html2canvas拿到一个html转为canvas的base64码,

  再在页面建立一个img元素,src=base64码,插入dom中,盖在所有元素的最上方(或者需要用户长按保存的地方),opacity设置为0。

  然后用户就长按保存,存下来的就是事先准备好的覆盖在那里的那个不可见得透明图。
  事实证明,图片透明不可见覆盖在页面上边,微信里是可以存图的。

  而很多市面上的h5,结果页和最后存下来的图不一样的,估计都是这么搞得,毕竟看不见代码

html2canvas+jsbridge同时存两张图
  html2canvas和jsbridge的存图功能协作时,会触发同时存两张图的现象。

  第一次存图很完美,如果不关掉页面第二次存图,就会存两张,以后也会存两张。只有第一次使用存图是好的。
  就是jsbridge调了两次,第二次自动调起的原因目前猜测是html2canvas引起的, 

  因为一层层定位,只有在html2canvas返回base64码后会有问题。具体原因暂没有找到。
  最后解决方法是:配合sessionStore,第一次截完图后,将图片地址存入sessionstore,

  之后判断,sessionstore里有base64码就不用html2canvas生成码了,直接取数据存图,

html2canvas触发时重新加载页面的所有静态资源(除js)
  css和img图像,这一点是在和Wdatapicker组合使用时发现的问题。

  本来没什么,爱加载几次加载几次,但是datapicker的样式是写在iframe里的,重新加载dom还把人家的样式给丢了。这事儿就大了
  大归大,问题根本原因没解决,还是治标不治本的在每次触发html2canvas截图保存pdf的时候,重新给datapicker绘制样式,就是这么任性!

html2canvas 截图跨域

  https://blog.csdn.net/yaosir1993/article/details/76474080

以下截取部分作者思想,主要是用于解决了本次问题的地方:
  useCORS:true 这个参数很重要,没有配置的话,依旧是不能解决问题的;
  根据现有的解决方案大致有两种:
  (1).在跨域的服务器上设置header设置为允许跨域请求。 在服务器上设置header设置允许跨域请求(采用nginx做静态资源映射) 
  (2).借助代理脚本获得外域图片的 base64 编码后的字符串
  
  关于跨域和清晰度解决方案的讲解地址:https://lengxing.github.io/
  设置header,实现跨域访问http://blog.csdn.net/enter89/article/details/51205752 

领导建议:

  域名反向代理,

  图片允许跨域使用:Access-Control-Allow-Origin: *;

html2canvas+qrcode 截二维码被白底遮挡

  html2canvas执行截图-因为页面中有一处是qrcode执行的地址转二维码,每次截图后二维码都截不下来,那一块就是一个白块
  后来把二维码img的外部div结构背景色设置半透明,二维码就截出来了,原来是div的背景色盖住了img
  原理还是搞不明白,明明层级都设置了还不起作用,竟然被自己的爹给盖住也是醉了。
  二维码处之所以为白色是因为外部结构的白色背景给覆盖了,最后是盛放二维码img的外部div结构不设置背景色就解决了


html2canvas截图时,背景音乐在ios11下会重复播放
解决方法见博文:https://blog.csdn.net/lerayZhang/article/details/79207468

技术分享图片
1 import html2canvas from ‘html2canvas/dist/html2canvas.min‘;
2 export { html2canvas };
html2canvas
技术分享图片
 1 /*
 2  * @Author: [email protected] 
 3  * @Date: 2017-12-25 15:18:12
 4  * html2image模块
 5  * @param {object=} parameter 参数配置
 6  * @param {string} parameter.targetEleId: 目标元素id--要截屏的区域
 7  * @param {string} parameter.imgType: 要保留下来的图片格式:png|jpg|bmp|gif
 8  * @param {Boolean} toDown: 是否执行下载功能,不执行则返回图片base64地址
 9 */
10 import { html2canvas } from ‘./html2canvas‘;
11 //解决ios11下,重复加载背景音乐的bug
12 const iosMusic = (idName)=>{  
13   let agent = navigator.userAgent.toLowerCase(),//判断手机系统  
14       version;  
15   // console.log(agent);  
16   if(agent.indexOf("like mac os x") > 0){  
17       //ios  
18       let regStr_saf = /os [d._]*/gi,  
19           verinfo = agent.match(regStr_saf) ;  
20       version = (verinfo+"").replace(/[^0-9|_.]/ig,"").replace(/_/ig,".");//获取具体的系统版本号  
21       let typeNum = version.split(".")[0];//获取系统版本号的第一位数字  
22       // console.log(version);
23       // console.log(typeNum);
24       if(typeNum >= 11){  
25         $(idName).removeAttr("autoplay");  
26       }  
27   }  
28 }
29 export let html2img = (parameter,toDown = true)=> {
30   const promise = new Promise((resolve,reject)=>{
31     if(parameter.imgType == ‘png‘ || parameter.imgType == ‘jpg‘ || parameter.imgType == ‘bmp‘ || parameter.imgType == ‘gif‘){
32       let type = parameter.imgType;
33       /**
34       * 获取mimeType
35       * @param  {String} type the old mime-type
36       * @return the new mime-type
37       */
38       const _fixType = function(type) {
39           type = type.toLowerCase().replace(/jpg/i, ‘jpeg‘);
40           let r = type.match(/png|jpeg|bmp|gif/)[0];
41           return ‘image/‘ + r;
42       };
43       /*图片跨域及截图模糊处理*/
44       let shareContent = parameter.targetEleId,//需要截图的包裹的(原生的)DOM 对象
45           width = shareContent.clientWidth,//shareContent.offsetWidth; //获取dom 宽度
46           height = shareContent.clientHeight,//shareContent.offsetHeight; //获取dom 高度
47           canvas = document.createElement("canvas"), //创建一个canvas节点
48           scale = 2; //定义任意放大倍数 支持小数
49       canvas.width = width * scale; //定义canvas 宽度 * 缩放
50       canvas.height = height * scale; //定义canvas高度 *缩放
51       canvas.style.width = shareContent.clientWidth * scale + "px";
52       canvas.style.height = shareContent.clientHeight * scale + "px";
53       canvas.getContext("2d").scale(scale, scale); //获取context,设置scale 
54       let opts = {
55           scale: scale, // 添加的scale 参数
56           canvas: canvas, //自定义 canvas
57           logging: false, //日志开关,便于查看html2canvas的内部执行流程
58           width: width, //dom 原始宽度
59           height: height,
60           useCORS: true // 【重要】开启跨域配置
61       };
62       /* html2canvas截图时,背景音乐重复播放问题。 */
63       iosMusic(parameter.musicId);
64       /* html2canvas 截图 */
65       html2canvas(shareContent,opts).then(function(canvas) {
66         let imgData = canvas.toDataURL(‘image/png‘);
67         // console.log(canvas.toDataURL(‘image/png‘).substring(0,20));
68         // console.log(canvas.toDataURL(‘image/png‘).length);
69         // let save_link = document.createElementNS(‘http://www.w3.org/1999/xhtml‘, ‘a‘);
70         // save_link.href = imgData.replace(_fixType(type),‘image/octet-stream‘);
71         if(toDown){
72           let link_title = parameter.titleStr ? parameter.titleStr + ‘_‘ : ‘easypass_‘;
73           save_link.download = link_title + (new Date()).getTime() + ‘.‘ + type;
74           let event = document.createEvent(‘MouseEvents‘);
75           event.initMouseEvent(‘click‘, true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
76           save_link.dispatchEvent(event);
77         }else{
78           resolve(imgData);
79         }
80       }); 
81     }else{
82       reject(new Error(‘parameter.imgType 类型错误,应该是字符串,且只有四种类型值。‘));
83     }
84   });
85   return promise;
86 }
html2img

 

具体配置根据自己需要进行调整。

最后调用:

 1 html2img({
 2     targetEleId: oCanvas,
 3     imgType: ‘png‘,
 4     titleStr: ‘测测你是哪种汽车人‘,
 5     musicId: ‘#musicAudio‘
 6   },false)
 7   .then((imgUrl)=>{
 8     let oImg = document.createElement(‘img‘);
 9     oImg.id = ‘oImg‘;
10     oImg.className = ‘o-img‘;
11     oImg.src= imgUrl;
12     document.body.appendChild(oImg);
13   });

 

2018-06-25  17:54:43  (持续更新中...)

 








































以上是关于Html2canvas - 项目中遇到的那些坑点汇总(更新中...)的主要内容,如果未能解决你的问题,请参考以下文章

Django2.2 静态文件的上传显示,遇到的坑点-------已解决

html2canvas 问题总结(跨域 黑边 超时)

html2canvas 离屏

遇到的坑点

html2canvas的使用

html2canvas 不能使用伪元素