Appearance
前言
相信有很多的小伙伴在开发过程中进行绘制图片,或者截图等,今天我把使用的做一个总结分享给大家,避免入坑。
安装html2canvas
js
npm i -D html2canvas
npm i -D html2canvas
引入html2canvas
在所需要使用的组件上引入html2canvas
js
import html2canvas from "html2canvas";
import html2canvas from "html2canvas";
添加ref获取元素
html部分:
js
<div class="m-html2canvas">
<div ref="canvasRef" class="m-canvasRef">
<div class="m-imageList" v-for="item in imageList" :key="item.id">
<img :src="item.path" alt="" />
</div>
</div>
<div class="m-showImage" v-if="imgUrl">
<img :src="imgUrl" alt="" />
</div>
<div class="m-btn">
<el-button type="primary" @click="createImageQrcode">合成图片</el-button>
</div>
</div>
<div class="m-html2canvas">
<div ref="canvasRef" class="m-canvasRef">
<div class="m-imageList" v-for="item in imageList" :key="item.id">
<img :src="item.path" alt="" />
</div>
</div>
<div class="m-showImage" v-if="imgUrl">
<img :src="imgUrl" alt="" />
</div>
<div class="m-btn">
<el-button type="primary" @click="createImageQrcode">合成图片</el-button>
</div>
</div>
data部分:
js
imageList: [
{
path: "https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF",
id: 1
},
{
path: "https://img2.baidu.com/it/u=3231735899,2029570314&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500",
id: 2
},
{
path: "https://t7.baidu.com/it/u=1956604245,3662848045&fm=193&f=GIF",
id: 3
}
],
imgUrl: ""
imageList: [
{
path: "https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF",
id: 1
},
{
path: "https://img2.baidu.com/it/u=3231735899,2029570314&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500",
id: 2
},
{
path: "https://t7.baidu.com/it/u=1956604245,3662848045&fm=193&f=GIF",
id: 3
}
],
imgUrl: ""
methods部分:
具体的html2canvas配置项可以看官网
js
methods: {
createImage() {
this.$nextTick(() => {
const canvas = document.createElement("canvas");
// 获取要生成图片的 DOM 元素
let canvasDom = this.$refs.canvasRef;
// 获取指定的宽高
const width = parseInt(window.getComputedStyle(canvasDom).width);
const height = parseInt(window.getComputedStyle(canvasDom).height);
// console.log("获取指定的宽高", width, height)
// 宽高扩大 2 倍 处理图片模糊
canvas.width = width;
canvas.height = height;
canvas.style.width = width / 2 + "px";
canvas.style.height = height / 2 + "px";
const context = canvas.getContext("2d");
context.scale(1, 1);
// context.fillStyle = '#FFFFFF'
context.fillRect(0, 0, canvas.width, canvas.height);
const options = {
backgroundColor: null,
canvas: canvas,
useCORS: true,//配置允许跨域
// scale:1,
// windowWidth: document.body.scrollWidth,
// windowHeight: document.body.scrollHeight,
// x: 0,
// y: window.pageYOffset,
// allowTaint: true,
// background: "#ffffff", // 一定要添加背景颜色,否则出来的图片,背景全部都是透明的
dpi: 300 // 处理模糊问题
};
console.log("获取指定的宽高", width, height, canvas);
html2canvas(canvasDom, options)
.then(canvas => {
try {
// 生成图片地址
this.imgUrl = canvas.toDataURL("image/png");
console.log("canvas.toDataURL('image/png')", this.imgUrl);
} catch (e) {
alert("图片跨域,保存失败");
}
})
.catch(err => {
console.log("绘制失败");
});
});
}
}
methods: {
createImage() {
this.$nextTick(() => {
const canvas = document.createElement("canvas");
// 获取要生成图片的 DOM 元素
let canvasDom = this.$refs.canvasRef;
// 获取指定的宽高
const width = parseInt(window.getComputedStyle(canvasDom).width);
const height = parseInt(window.getComputedStyle(canvasDom).height);
// console.log("获取指定的宽高", width, height)
// 宽高扩大 2 倍 处理图片模糊
canvas.width = width;
canvas.height = height;
canvas.style.width = width / 2 + "px";
canvas.style.height = height / 2 + "px";
const context = canvas.getContext("2d");
context.scale(1, 1);
// context.fillStyle = '#FFFFFF'
context.fillRect(0, 0, canvas.width, canvas.height);
const options = {
backgroundColor: null,
canvas: canvas,
useCORS: true,//配置允许跨域
// scale:1,
// windowWidth: document.body.scrollWidth,
// windowHeight: document.body.scrollHeight,
// x: 0,
// y: window.pageYOffset,
// allowTaint: true,
// background: "#ffffff", // 一定要添加背景颜色,否则出来的图片,背景全部都是透明的
dpi: 300 // 处理模糊问题
};
console.log("获取指定的宽高", width, height, canvas);
html2canvas(canvasDom, options)
.then(canvas => {
try {
// 生成图片地址
this.imgUrl = canvas.toDataURL("image/png");
console.log("canvas.toDataURL('image/png')", this.imgUrl);
} catch (e) {
alert("图片跨域,保存失败");
}
})
.catch(err => {
console.log("绘制失败");
});
});
}
}
style部分:
js
.m-html2canvas {
display: flex;
}
.m-canvasRef {
width: 500px;
height: 500px;
/* border: 1px solid red; */
/* box-sizing: border-box; */
box-shadow: 10px 10px 5px #888888;
}
.m-imageList {
width: 500px;
height: calc(500px / 3);
}
img {
width: 100%;
height: 100%;
float: left;
}
.m-showImage {
margin-left: 50px;
background: red;
width: 500px;
height: 500px;
}
.m-btn {
margin-left: 50px;
}
.m-html2canvas {
display: flex;
}
.m-canvasRef {
width: 500px;
height: 500px;
/* border: 1px solid red; */
/* box-sizing: border-box; */
box-shadow: 10px 10px 5px #888888;
}
.m-imageList {
width: 500px;
height: calc(500px / 3);
}
img {
width: 100%;
height: 100%;
float: left;
}
.m-showImage {
margin-left: 50px;
background: red;
width: 500px;
height: 500px;
}
.m-btn {
margin-left: 50px;
}
以上就是简单的一种html2canvas的截图使用了。这里会有一个问题存在,因为生成的图片是base64的,将base64地址复制打开的时候图片的底部会失去一部分成了白色,但是在页面中直接显示的话是正常的,至今没能找到原因。
跨域问题
在配置了useCORS = true后还是会出现跨域问题,譬如这样:
有两种解决方式:
第一种:后端需要在服务器IIS上的HTTP响应标头设置,最简单粗暴的方法就是全部设置成*,不过这样安全性也低,自己可以根据自己需求设置:
js
access-control-allow-credentials:true
Access-Control-Allow-Headers:*
access-control-allow-origin:*
access-control-allow-credentials:true
Access-Control-Allow-Headers:*
access-control-allow-origin:*
第二种:在img标签上设置 crossorigin="anonymous"
属性,但是这样还是不行的,还是会报跨域问题,最后在src图片地址后面加上时间戳,有人说要加固定的参数,不然没有缓存,会一直请求,因为我们的页面渲染的时候,有协商缓存和强缓存的说法,大部分用来减少当页面刷新时,防止页面多次跟服务器请求,当我们国内访问github是一样的道理。但是我用的时候发现加上固定参数还是会报跨域问题。
js
......
<img
:src="staffQrCodeDialogBg1 + '?' + new Date().getTime()"
alt=""
crossOrigin="anonymous"
/>
......
......
<img
:src="staffQrCodeDialogBg1 + '?' + new Date().getTime()"
alt=""
crossOrigin="anonymous"
/>
......
我一般都是使用第二种,前端自行解决,速度快,效率高
总结
html2canvas填坑之旅就这样完成了,一共有三个问题,图片模糊问题、跨域问题、图片底部留白问题
今年打算逼自己去总结和学习,规划一定的时间来写文章来分享自己的所遇所学,来帮助大家避免入坑。