1、HTML2Canvas
Html2canvas 使您可以直接在用户浏览器上截取网页或部分网页的“屏幕快照”。屏幕截图基于DOM,脚本遍历加载页面的DOM,收集目标节点的所有元素信息,然后将其用于构建页面的表示形式。换句话说,它实际上并非是截取页面,而是根据它从DOM读取的属性来构建页面的表现形式,因此不能保证100%还原原图。
官方文档:http://html2canvas.hertzen.com/documentation

2、使用方法

html2canvas(element).then(canvas => {
    // canvas 为转换后的Canvas对象
    let oImg = new Image();
    oImg.src = canvas.toDataURL(); // 返回base64 data图片url数据, 可在toDataURL()添加参数设置图片格式,默认png
    document.body.appendChild(oImg); // 将生成的图片添加到body
})

3、常见问题与解决方案

##### 1\. 图片模糊问题

问题:有时候我们会发现,导出的图片局部有些图片看起来没有原图那么清晰。

方案1:或许是因为目标节点内使用背景图片的原因,建议使用<img>标签替代背景图样式

方案2:如果还是会模糊,可以先将canvas画布放大,然后再将生成后图片等比缩放

var width \= element.offsetWidth;  
var height \= element.offsetHeight;  
var canvas \= document.createElement(“canvas”);  
var scale \= 2;  
​  
canvas.width \= width \* scale; // 放大画布  
canvas.height \= height \* scale; // 放大画布  
canvas.getContext(“2d”).scale(scale,scale); // 2d绘制且将canvas画布横坐标纵坐标各放大2倍。  
​  
var opts \= {  
 scale: scale,  
 canvas: canvas,  
 width: width,  
 height: height  
 }  
​  
html2canvas(element, opts).then(canvas \=> {  
 var dataUrl \= canvas.toDataUrl(); // 生出图片base64格式url  
 var newImg \= document.createElement(“img”); // 创建img元素  
 newImg.src \= dataUrl; // 给img元素指定路径  
 newImg.style.widht \= canvas.width/scale + ‘px’; // 等比缩放生出图片宽度  
 newImg.style.height \= canvas.height/scale + ‘px’; // 等不缩放生成图片高度  
 })

方案3:另一种方法是给html2canvas添加配置项参数

html2canvas(element, {  
 scale: 2,  // 画布放大2倍  
 dpi: 300 // 根据需要将分辨率提高到特定的DPI(每英寸点数), 默认值为96  
}).then(canvas \=> {  
 // do something  
})

##### 2\. 图片不显示问题

问题:有时候可能莫名其妙地发现有些图片并没有出现在导出的图片中

方案:基本上是因为图片素材出现跨域,使用html2canvas时添加以下两个配置项

html2canvas(element, {  
 allowTaint: true, // 是否允许跨域图像污染画布  
 useCORS: true // 是否尝试使用CORS从服务器加载图像  
}).then(canvas \=> {  
 // do something  
})

##### 3\. PNG图片不透明问题

问题:有时候可能用到透明的PNG图片作为背景图,可是结果最后生成的图片却并不透明,这是因为html2canvas生出的canvas背景颜色默认为白色的缘故,所以导出的图片背景颜色也是白色

方案:使用html2canvas时添加backgroundColor配置项就好

html2canvas(element, {  
 backgroundColor: “transparent”, // 也可以是rgba(0,0,0,0)  
}).then(canvas \=> {  
 // do something  
})

##### 4\. 在IOS系统部分浏览器中,用'<br/>'标签进行文字换行时,文本只显示第一行

问题:在IOS系统部分浏览器中,用<br/>标签进行文字换行时,文本只显示第一行

方案:出现该问题时,采用其他块级标签元素对需要进行换行的文字分别包裹

Html2canvas, <br/> 文本只显示第一行  
可替换成  
<ul\>  
 <li\>html2canvas,</li>  
 <li\>文本只显示第一行</li>  
</ul>

##### 5\. 截图不全

问题:在生成图片的时候,如果需要生成图片的节点很长(伴有滚动条),只能截取到当前区域

方案1:找到需要生成截图的dom节点,在页面渲染完成之后,克隆一份备份节点,追加到body后面,这份备份节点不能是隐藏状态,设置备份节点的绝对定位和图层级别

// 获取节点高度,后面为克隆节点设置高度  
var height \= document.getElementById (‘targetNode’). offsetHeight;  
// 克隆节点,默认为false,不复制方法属性,为true是全部复制  
var cloneDom \= document.getElementById (‘targetNode’).cloneNode(true);  
// 设置克隆节点的css属性,因为之前的层级默认为0,我们需要比被克隆的节点层级低  
cloneDom.style.cssText \= “background\-color: white; position: absolute; top: 0; z\-index: \-1;”  
cloneDom.style.height \= height + ‘px’;  
// 将克隆节点追加到body后面  
document.body.appendChild(cloneDom);   
​  
html2cavans(cloneDom, {  
 allowTaint: true,  
 onrendered: function (canvas) {  
 // do something   
 }  
}) 

方案2:在生出截图前,先把滚动条置顶

window.pageYoffset \= 0;  
document.documentElement.scrollTop \= 0;  
document.body.scrollTop \= 0;  
​  
或者在配置列表添加参数配置  
html2canvas(element, {  
 scrollY: 0,  
}).then(canvas \=> {  
 // do something  
})

### 案例代码

html2canvas(element, {  
 backgroundColor: ‘transparent’, // 解决生出图片不透明问题  
 allowTaint: true,             // 解决图片跨域问题  
 useCORS: true,              // 解决图片跨域问题  
 scrollY: 0,                  // 解决截图不全问题  
 scale: 2,                   // 解决生出图片不清晰问题  
 dpi: 300,                   // 解决生出图片不清晰问题  
}).then(canvas \=> {  
 let img \= new Image();                   // 新建img节点  
 let url \= canvas.toDataURL(‘imgae/png’);     // 获取生出图片src路径  
 let aLink \= document.createElemtn(‘a’);      // 创建a标签  
 aLink.style.display \= ‘none’;  
 aLink.href \= url;  
 aLink.download \= ‘下载文件名xxx.png’;  
 // 触发下载效果后移除节点  
 document.body.appendChild(aLink);  
 aLink.click();  
 document.body.removeChild(aLink);  
 })

JohnsonGH
32 声望1 粉丝