npm install html2canvas
npm install canvg
html2canvas 将页面保存在canvas进行图片保存
canvg 将页面中的svg转化为canvas
1.1 启动canvg引擎
from和fromString的区别是from需要传入的是svg本身,而fromString需要传入的是svg的字符串形式。这三种方式都可以传入三个参数,第一个参数是canvas画布的绘制上下文,第二个是需要绘制的svg,第三个是自定义配置选项,可以用于控制画布的渲染结果。
1.2 canvg启动渲染的方法有两种:render
、start
。
区别是当需要绘制的svg是动态图时,render
只会绘制第一帧的内容,也就是说绘制出来的图像是静态的,而start
是会将svg的内容以及动效全部都绘制出来,也就是说图片是动态的形式。
import html2canvas from 'html2canvas';
import { Canvg } from 'canvg'
<div class="svg-box">
<svg class='svg' width="100%" height="100%" viewBox="0 0 200 200" ref="svg">
<!-- 外圈圆 -->
<circle cx="100" cy="100" r="90" stroke="#dcdcdc" stroke-width="10" fill="none" />
<!-- 内圈圆,虚线用于展示进度 -->
<circle cx="100" cy="100" r="90" stroke="#ff0000" stroke-width="10" fill="none" :stroke-dasharray="Math.PI*45 +','+ 2*Math.PI*90" :stroke-dashoffset="0" stroke-linecap="round" transform="rotate(-90,100,100)"></circle>
</svg>
</div>
this.$nextTick(async () => {
const parentNode = this.$refs.svg.parentNode;
const svg = this.$refs.svg.outerHTML.trim();
let canvasDom = document.createElement('canvas')
let ctx = canvasDom.getContext('2d')
canvasDom.setAttribute('width', this.$refs.svg.clientWidth+'px')
canvasDom.setAttribute('height', this.$refs.svg.clientHeight+'px')
canvasDom.setAttribute('style', 'display:block;')
document.body.appendChild(canvasDom)
const v = Canvg.fromString(ctx, svg);
await v.render();
parentNode.removeChild(this.$refs.svg);
parentNode.appendChild(canvasDom);
html2canvas(this.$refs.imgDom, {
useCORS: true // 允许CORS跨域
}).then((canvas) => {
this.imgUrl = canvas.toDataURL("image/png")
// 触发图片下载
const aElem = document.createElement('a')
document.body.appendChild(aElem)
aElem.href = this.imgUrl
// 设置下载标题
aElem.download = "chart.jpg"
aElem.click()
document.body.removeChild(aElem)
});
})
1.背景图片模糊
解决方案:使用img标签来实现background-image的效果
2.图片无法渲染
在img标签内加入crossorigin=‘anonymous’(crossorigin='anonymous’可以触发带跨域请求头Origin的HTTP请求)并给html2canvas设置allowTaint: true配置
3.跨域加载的图片会污染canvas,进而导致canvas无法导出数据
解决方案1:给html2canvas设置useCORS:true加载跨域图像的配置,并且保证给每个图片添加添加crossOrigin="anonymous"属性
解决方案2:将文件读入到blob文件对象,然后用URL.createObjectURL()方法转换成img src可用的地址,然后再转canvas
注意:读入blob文件时保证要设置的img标签内的src为空,在读入文件完成后在调用生成图片函数
// 将文件读入到blob文件在转img的方法
function getImage ( url ) {
const xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.responseType = 'blob';
xhr.onload = function () {
if (this.status == 200) {
this.imgUrl = URL.createObjectURL(this.response);
}
};
xhr.send();
}
let urltest = '跨域图片链接'
getImage(urltest,'test-img')