一、需求
生成一张名片,名片上有用户信息以及二维码,名片支持下载功能(背景样式可更换,忽略本文章样图样式)。
二、参考文章
这不是我自己找官网自己摸索出来的,是借鉴各位前辈的,学以致用,自己运用到项目中实现需求,做个记录,以便将来需要,方便查看
链接:
Vue中两种生成二维码(带logo)并下载方式_vue qrcode logo图标-CSDN博客
vue中html2canvas的使用_vue html2canvas-CSDN博客
三、实现代码
1.qrcode生成二维码
下载依赖
npm i qrcode
注:这里我将生成二维码的实现封装成一个组件,以便复用
HTML:
html
<template>
<div class="qrcode-box">
<!-- 二维码主要部分 -->
<canvas id="canvas" ref="qrCanvas" title="扫描二维码"></canvas>
<!-- logo 用定位定到二维码中间的 -->
<div class="card-logo">
<img
src="../../assets/images/userCard/card_logo.png"
class="card-img"
alt="名片"
/>
</div>
</div>
</template>
JS:这里只生成了二维码
javascript
<script>
import QRCode from "qrcode"; //引入生成二维码插件
export default {
name: "qrcode",
props: {
canvasWidth: {//画布的宽度
default: 87,
type: Number,
},
canvasHeight: {//画布的高度
default: 87,
type: Number,
},
url: {//生成二维码的地址
default: "",
// type: String,
required: true,
},
logoUrl: {//二维码的logo
default: require("@/assets/images/userCard/card_logo.png"),
type: String,
// required:true
},
},
mounted() {
//生成二维码
this.generateQRCode();
//设置logo图标,这里是可以生成logo的,但是设计稿的二维码宽高小于100,导致生成的二维码模糊,所以我用定位的方式将logo定位到二维码中间
// if (this.logoUrl != "") {
// let myCanvas = this.$refs.qrCanvas;
// let ctx = myCanvas.getContext("2d");
// // 在Canvas画布 添加图片
// let img = new Image();
// // img.setAttribute("crossOrigin", "Anonymous");
// img.crossOrigin = "Anonymous"; //解决Canvas.toDataURL 图片跨域问题
// img.src = this.logoUrl;
// img.onload = () => {
// //第一个设置的元素,第二三是位置,后面两个是宽和高
// //居中的位置计算为 (二维码宽度-img宽度)/2
// let codeWidth = (this.canvasWidth * 0.75) / 2;
// let codeHeight = (this.canvasHeight * 0.75) / 2;
// ctx.drawImage(
// img,
// codeWidth,
// codeHeight,
// this.canvasWidth * 0.25,
// this.canvasHeight * 0.25
// );
// };
// }
},
data() {
return {};
},
methods: {
// 生成的二维码宽高小于100的时候会读取不到信息,生成的二维码信息不够齐全,模糊
generateQRCode() {
let opts = {
errorCorrectionLevel: "M", //4个容错级别(L:7%, M: 15%, Q: 25%, H: 30%),指二维码被遮挡可以扫出结果的区域比例
type: "image/png", //生成的二维码类型
quality: 0.3, //二维码质量
margin: 1, //二维码留白边距
width: this.canvasWidth, //宽
height: this.canvasHeight, //高
text: "1111", //二维码内容
color: {
light: "#ffffff", //背景色
},
};
// 将获取到的数据(val)画到msg(canvas)上,加上时间戳动态生成二维码
const canvas = this.$refs.qrCanvas;
QRCode.toCanvas(canvas, this.url, opts, (error) => {
if (error) console.error(error);
});
},
},
};
</script>
CSS:
css
<style lang="scss" scoped>
.qrcode-box {
position: relative;
.card-logo {
width: 20px;
height: 20px;
position: absolute;
top: 34px;
left: 34px;
img {
width: 100%;
height: 100%;
}
}
}
</style>
2.html2canvas 生成图片(这里只展示部分代码)
二维码logo在这里用定位定到二维码中间,我将名片也封装了一个组件
html
<div class="qrcode_pic" v-if="cardInfo.qrCodeUrl">
<QRcodeComponent :url="cardInfo.qrCodeUrl" />
<div class="qrcode_text">
<img
src="../../../../../assets/images/userCard/qrcode_text.png"
class="code-img"
alt="二维码"
/>
</div>
</div>
这里是下载使用的组件
html
<div class="card-box">
<div class="down_btn">
<el-button type="text" @click="download">
<i class="el-icon-download"></i>
下载</el-button
>
</div>
<div ref="content" class="down-content">
<UserCard />
</div>
</div>
javascript
<script>
import html2canvas from "html2canvas";
data(){
download() {
const ref = this.$refs.content; // 截图区域
html2canvas(ref, {
// 以下字段可选
width: 560, // canvas宽度
height: 355, // canvas高度
x: 0, // x坐标
y: 0, // y坐标
scrollY: 0,
scrollX: 0,
backgroundColor: null,
// backgroundColor: "#e8f4ff",
padding:0,
borderRadius: 5,
scale: 2, // 处理模糊问题:按照比例增加分辨率,默认值1,
dpi: 300, // 处理模糊问题:每英寸的像素,也就是扫描精度,dpi越低,扫描清晰度越低,默认值96,建议修改为300
useCORS: true, // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
}).then((canvas) => {
const dataURL = canvas.toDataURL("image/png");
const creatDom = document.createElement("a");
document.body.appendChild(creatDom);
creatDom.href = dataURL;
creatDom.download = "我的名片";
creatDom.click();
});
},
}
</script>
四、遇到的问题及解决方案
1.二维码logo模糊
刚开始我是在mounted里直接用画布生成,但是很模糊,经过查找发现可以用定位将logo定到二维码中间,可以实现效果,在上面代码上有注释标明。
2.名片下载模糊
之前我是将图片以背景图片的形式放到盒子里,这样我用html2canvas 生成图片下载下来后很模糊,我就用img的形式定位到盒子上,下载后就清晰很多啦
css
// background-image: url("../../../../../assets/images/userCard/card.png");
// background-size: cover;
html
<div class="qrcode_pic" v-if="cardInfo.qrCodeUrl">
<QRcodeComponent :url="cardInfo.qrCodeUrl" />
<div class="qrcode_text">
<img
src="../../../../../assets/images/userCard/qrcode_text.png"
class="code-img"
alt="二维码"
/>
</div>
</div>
五、恭喜恭喜
恭喜你我又学会了新的东西,真棒呀真棒呀,祝你我今天开心呐,有问题请留言,看见就会回的,不过不一定会。