需求描述:在公众号中,生成二维码,并在二维码中央添加自定义logo,然后生成一张分享给好友的 二维码图片。
一、用到的依赖包
npm install --save html2canvas
<script src='https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js'></script>
<script src="https://cdn.bootcss.com/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>
<template>
<div>
<div class="userBox">
<div id='qrcode'></div>
</div>
<el-dialog :visible="dialogTableVisible" width="90%" @close="closeDialog" top="10vh">
<img src="../../image/close-btn.png" class="close-btn" @click="closeDialog" alt="">
<div v-if="!shareQrImg" class="qr-bg" id="qrBg" >
<h2>关注公众号开启平台功能</h2>
<div id="imgContainer" class="imgContainer"></div>
<span>长按二维码,分享给好友!</span>
<img src="../../image/dialog-bg.png" class="qr-bg-img" alt="">
</div>
<!--这个img 标签,可以在手机端长按分享图片-->
<img v-else :src="shareQrImg" alt="" style="width: 326px; height: 467px;">
</el-dialog>
</div>
</template>
<script>
data () {
return {
canvas: null,
canvaswidth: 0,
canvasheight: 0,
// 二维码宽高
qrcodewidth: 400,
qrcodeheight: 400,
qrcodeTopOffset: 59,
dialogTableVisible: false,
shareQrImg: ''
};
},
async created() {
//canvas宽高
this.canvaswidth = this.qrcodewidth;
this.canvasheight = this.qrcodeheight + this.qrcodeTopOffset + 50;
},
methods: {
closeDialog () {
this.dialogTableVisible = false;
$('#imgContainer').empty();
$('#qrcode').empty();
this.shareQrImg = '';
this.canvas.width = this.canvaswidth;
this.canvas.height = this.canvasheight;
var ctx = this.canvas.getContext('2d');
ctx.clearRect(0, 0, this.canvaswidth, this.canvasheight);
},
//解决中文乱码问题
toUtf8(str) {
var out, i, len, c;
out = "";
len = str.length;
for (i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
},
initQrCodeImg (url) {
try {
//二维码宽高
//logo宽高
var logowidth = 84;
var logoheight = 84;
//文字描述位置
var textleft = this.qrcodewidth / 2;
var texttop = 39;
//logo位置
var logoleft = (this.qrcodewidth - logowidth) / 2;
var logotop = (this.qrcodeheight - logoheight) / 2 + this.qrcodeTopOffset;
const qrcode = $('#qrcode');
qrcode.qrcode({
render : 'canvas',
text : this.toUtf8(url),
width : this.qrcodewidth,
height : this.qrcodeheight,
background : '#ffffff',
foreground : '#000000',
});
this.canvas = qrcode.find('canvas').get(0);
var img = new Image();
img.crossOrigin = 'anonymous';
img.src = this.canvas.toDataURL('image/png');
img.onload = () => {
this.canvas.width = this.canvaswidth;
this.canvas.height = this.canvasheight;
var ctx = this.canvas.getContext('2d');
//设置画布背景
ctx.fillStyle = 'transparent';
ctx.fillRect(0, this.qrcodeTopOffset, this.canvas.width, this.canvas.height);
//设置文字样式
ctx.fillStyle = '#7E7E7E';
ctx.font = '400 ' + 29 + 'px PingFangSC, PingFang SC';
ctx.textAlign = 'center';
//文字描述
ctx.fillText("AD中台,您的高效拍档!", textleft, texttop);
ctx.fillStyle = '#BBBBBB';
ctx.font = '400 ' + 26 + 'px PingFangSC, PingFang SC';
ctx.textAlign = 'center';
//文字描述
const date = new Date(Date.now() + 7 * 86400000);
const month = (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1);
const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
ctx.fillText(`有效期至${date.getFullYear()}-${month}-${day}`, textleft, this.qrcodeTopOffset + this.qrcodeheight + 42);
//绘制二维码
ctx.drawImage(img, 15, this.qrcodeTopOffset + 12, this.canvaswidth - 30, this.canvasheight - 120);
//设置logo
var logo = new Image(logowidth, logoheight);
logo.src = '../../image/qr-logo.png';
logo.onload = () => {
ctx.drawImage(logo, logoleft, logotop, logowidth, logoheight);
this.dialogTableVisible = true;
this.$nextTick(() => {
var image = new Image();
image.crossOrigin = 'anonymous';
image.classList.add('imgContainer');
image.src = this.canvas.toDataURL('image/png');
document.getElementById('imgContainer').appendChild(image);
// 替换为目标元素的id或class
const element = document.getElementById('qrBg');
html2canvas(element, {
backgroundColor: null,
scale: 7.5,
height: element.scrollHeight - 1,
width: element.scrollWidth - 2,
dpi: window.devicePixelRatio * 2, //设备像素比
x: 1
}).then((canvas) => {
const image = canvas.toDataURL('image/png');
this.shareQrImg = image;
});
});
}
}
} catch (e) {
console.error(123, e);
}
},
}
</script>
<style>
.imgContainer {
width: 176px;
}
#qrcode {
display: none;
position: absolute;
top: 0px;
left: -500px;
}
.el-dialog {
background-color: transparent;
box-shadow: none;
}
.el-dialog__body {
display: flex;
justify-content: center;
padding: unset;
}
.el-dialog__headerbtn {
display: none;
}
.qr-bg {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 326px;
height: 467px;
background-color: transparent;
}
.qr-bg .qr-bg-img {
position: absolute;
width: 326px;
height: 467px;
z-index: -1;
}
.qr-bg h2 {
margin-top: 117px;
font-family: PingFangSC, PingFang SC;
color: #000000;
font-weight: 600;
font-size: 18px;
}
.qr-bg span {
margin-top: 11px;
font-family: PingFangSC, PingFang SC;
font-weight: 600;
font-size: 16px;
color: #3E8BFD;
}
</style>