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 };
 1 /*
 2  * @Author: guojufeng@ 
 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 }

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

最后调用:

 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  (持续更新中...)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

4 条评论
登录 后参与评论

相关文章

来自专栏程序猿

用 Python 向你比个心

之前写了一篇用 Python 画一个小猪佩奇和哆啦 A 梦,然后最近看到有人用 turtle 画了一个心,觉得挺有意思的,于是把代码复制到本地,再加了个播放音乐...

1545
来自专栏技术小讲堂

ASP.NET AJAX(12)__浏览器兼容功能判断浏览器的类型和版本Sys.Browser针对DOM元素的兼容操作针对DOM事件的兼容操作

目前,常见的浏览器IE(6,8,9),chrome,firefox,safari等,还有国内的一些曾经靠恐吓用户来提高使用率的某浏览器(河蟹社会),这些浏览器对...

3729
来自专栏Windows Community

Extensions in UWP Community Toolkit - FrameworkElement Extensions

概述 UWP Community Toolkit Extensions 中有一个为FrameworkElement 提供的扩展 - FrameworkEleme...

3398
来自专栏向治洪

React Native在Android平台运行gif的解决方法

概述 目前RN在Android平台上不支持gif格式的图片,而在ios平台是支持的,期待以后的版本中系统也是可以默认支持Android的。首先说下在ios平台怎...

2965
来自专栏Google Dart

Flutter Widget框架之旅 顶

Flutter小部件采用现代反应式框架构建,从React中获得灵感。 中心思想是你从小部件中构建你的UI。 小组件描述了他们的视图在给定其当前配置和状态时应该看...

1222
来自专栏hrscy

iOS 9 Storyboard 教程(二上)介绍Segue静态单元格(static cell)

Add Player 最终的设计看上去像下面这样:#接第一部分: 原帖地址 简书地址

771
来自专栏向治洪

React Native在Android平台运行gif的解决方法

概述 目前RN在Android平台上不支持gif格式的图片,而在ios平台是支持的,期待以后的版本中系统也是可以默认支持Android的。首先说下在ios平台怎...

1816
来自专栏Create Sun

【.net+jquery】绘制自定义表单(含源码)

前言   两年前的时候就想做一个类似的功能,当时思路大家都讨论好了,诸多原因最终还是夭折了。没想到两年多后再这有重新提出要写一个绘制表单的功能。对此也是有点小激...

6348
来自专栏技术墨客

React学习(7)—— 高阶应用:性能优化 原

在React内部已经使用了许多巧妙的技术来最小化由于Dom变更导致UI渲染所耗费的时间。对于很多应用来说,使用React后无需太多工作就会让客户端执行性能有质的...

772
来自专栏前端说吧

canvas - drawImage()方法绘制图片不显示的问题

事情是这样的,在我看完w3c的介绍和很有说服力和教学力的demo后,本着实践出真知的思想决定上手一试,这一试不要紧~

991

扫码关注云+社区