要求:实现接口返回不同的logo图来替换了二维码中的logo最后下载有背景图又二维码有logo的功能
安装包
npm install qrcode
npm install html2canvas
实现效果
<template>
<div>
<el-dialog
:visible.sync="qrCodeDialogVisible"
append-to-body
title="支付二维码"
width="500px"
>
<div class="dialog-box">
<el-button
style="margin-bottom: 10px; background-color: #4884fe"
type="primary"
@click="saveCode"
>
下载二维码
</el-button>
<div ref="boxCanvasRef">
<div
style="display: flex; flex-direction: column; align-items: center"
>
<el-image :src="bgImg" fit="fit" style="height: 480px"></el-image>
</div>
<div class="qr-code">
<canvas id="QRCode_header" ref="canvas" title="扫描二维码"></canvas>
<!-- <div class="mask-code" @click="saveCode">-->
<!-- <i></i><span>保存二维码</span>-->
<!-- </div>-->
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import QRCode from "qrcode"; // 引入生成二维码插件
import logo from "@/img/logo2.png";
import bgImgUrl from "@/img/img027.jpg";
import html2canvas from "html2canvas"; // 引入 html2canvas
export default {
name: "CodeS",
data() {
return {
qrCodeDialogVisible: false,
url: "https://www.baidu.com",
logoUrl: logo,
bgImg: bgImgUrl,
};
},
props: {
canvasWidth: {
default: 165,
type: Number,
},
canvasHeight: {
default: 170,
type: Number,
},
},
methods: {
showDialog() {
this.qrCodeDialogVisible = true;
this.$nextTick(() => {
this.getQRCode();
});
},
getQRCode() {
if (!this.url) {
console.error("没有提供 URL,无法生成二维码");
return;
}
const opts = {
errorCorrectionLevel: "H", // 容错级别
type: "image/png", // 生成二维码类型
quality: 0.8, // 二维码质量
margin: 1, // 二维码边距
width: this.canvasWidth, // 宽度
height: this.canvasHeight, // 高度
text: this.url, // 二维码内容
color: {
light: "#fff", // 背景色
},
};
QRCode.toCanvas(this.$refs.canvas, this.url, opts, (error) => {
if (error) {
console.log("二维码生成失败!", error);
} else {
// 二维码生成成功后处理 logo
this.addLogoToCanvas();
}
});
},
addLogoToCanvas() {
if (this.logoUrl) {
const myCanvas = this.$refs.canvas;
const ctx = myCanvas.getContext("2d");
const img = new Image();
img.crossOrigin = "Anonymous"; // 解决Canvas.toDataURL图片跨域问题
img.src = this.logoUrl;
img.onload = () => {
// 计算 logo 绘制的位置,居中
const codeWidth = (this.canvasWidth * 0.75) / 2;
const codeHeight = (this.canvasHeight * 0.75) / 2;
ctx.drawImage(
img,
codeWidth,
codeHeight,
this.canvasWidth * 0.3,
this.canvasHeight * 0.25
);
};
img.onerror = () => {
console.error("Logo 图片加载失败");
};
}
},
saveCode() {
const boxElement = this.$refs.boxCanvasRef; // 获取需要渲染的 DOM 元素
html2canvas(boxElement, {
useCORS: true, // 支持跨域(如加载图片)
}).then((canvas) => {
// 将 Canvas 转换为图片
const imageData = canvas.toDataURL("image/png");
// 创建一个下载链接
const link = document.createElement("a");
link.href = imageData;
link.download = `下载图片_${Date.now()}.png`; // 设置下载的文件名
link.click();
});
},
},
};
</script>
<style scoped>
.dialog-box {
position: relative;
flex-direction: column;
align-items: center;
}
.qr-code {
display: flex;
width: fit-content;
width: -webkit-fit-content;
width: -moz-fit-content;
position: absolute;
top: 57%;
left: 50%;
transform: translate(-50%, -50%);
}
.qr-code:hover > div {
z-index: 0;
}
.mask-code {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
z-index: -1;
}
.mask-code i {
display: inline-block;
width: 25px;
height: 25px;
background-size: cover;
}
.mask-code span {
color: white;
}
</style>