使用场景
点击按钮弹出弹窗,显示截图出来的图片。点击保存按钮调用接口保存图片到服务器。
封装html2canvas的使用组件
新建screenshot.vue文件
<template>
<el-dialog
title="截图"
:visible.sync="dialogShow"
width="50%"
@close="handleClose"
>
<div v-if="!imgUrl">正在获取截图信息</div>
<el-image :src="imgUrl" alt="" v-else>
<div slot="error" class="image-slot">截图失败,请重试</div>
</el-image>
<el-button @click="addImageData"> 保存图片 </el-button>
</el-dialog>
</template>
<script>
import html2canvas from 'html2canvas';
import { dataURLToFile } from './helper/util.js';
export default {
data() {
return {
// 图片数据
imgUrl: '',
dialogShow: false,
};
},
methods: {
// 打开弹窗显示截图
showImage(dom) {
this.saveImage(dom).then((url) => {
this.imgUrl = url;
});
this.dialogShow = true;
},
// 添加图片的方法
async addImageData() {
let formData = new FormData();
formData.append("file_01", dataURLToFile(this.imgUrl, ".jpg"));
//上传图片的方法
let res = await uploadImage(formData);
if (res.code == 200) {
//这里处理上传成功之后的相关逻辑
}
else {
this.$message.warning("请稍后再试!");
}
},
//通过点击,生成截图图片
saveImage(dom) {
//dom为需要生成截图数据的元素dom
return html2canvas(dom, { useCORS: true })
.then((canvas) => {
return canvas.toDataURL("image/jpeg");
});
},
//关闭弹窗的时候触发
handleClose() {
this.imgUrl = ''
this.dialogShow = false
},
}
}
</script>
helper/util.js
//获取图片的数据转成file格式
export function dataURLToFile(dataurl, filename) {
let arr = dataurl.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
使用html2canvas组件
在vue中,封装一个弹窗,在需要用到的页面引入即可。
<!-- 截图弹层 -->
<Screenshot
ref="Screenshot"
></Screenshot>
// 生成截图信息,dom为需要生成截图数据的元素dom
showScreenshot() {
const dom = this.$refs.XXX.$el;
this.$refs.Screenshot.showImage(dom);
},
如果dom中含有的不需要截图的元素。那么就可以过滤不需要元素。
从渲染中删除匹配元素的谓词函数。
saveImage(dom) {
return html2canvas(dom, {
useCORS: true, //是否尝试使用 CORS 从服务器加载图像
ignoreElements(element) {
//需要过滤的类名数组集合
let classList = ["BtnComponent"];
for (let i = 0; i < classList.length; i++) {
if (element.classList.contains(classList[i])) {
return true;
}
}
},
})
.then((canvas) => {
return canvas.toDataURL("image/jpeg");
});
},
允许跨域资源共享
useCORS: true, //是否尝试使用 CORS 从服务器加载图像
不支持的 CSS 属性
- background-blend-mode
- border-image
- box-decoration-break
- box-shadow
- filter
- font-variant-ligatures
- mix-blend-mode
- object-fit
- repeating-linear-gradient()
- writing-mode
- zoom
因为html2canvas目前不支持盒子阴影,所以如果截图的时候含有阴影会非常难看。
目前的解决办法有两种
(1)使用ignoreElements过滤含有阴影的元素。
(2)添加一个变量cutting:false
//通过点击,生成截图图片
saveImage(dom) {
this.cutting = true
//dom为需要生成截图数据的元素dom
return html2canvas(dom, { useCORS: true })
.then((canvas) => {
this.cutting = false
return canvas.toDataURL("image/jpeg");
});
},
//添加行内样式
:style="{
boxShadow: cutting ? 'none' : '0px 6px 21px 0px rgba(0, 0, 0, 0.1)',
}"
//或者使用动态类名
:class={noneBoxShadow : cutting === true}'