要求实现接口返回不同的logo图来替换了二维码中的logo最后下载有背景图又二维码有logo的功能

75 阅读1分钟

要求:实现接口返回不同的logo图来替换了二维码中的logo最后下载有背景图又二维码有logo的功能

安装包

npm install qrcode

npm install html2canvas

实现效果

image.png

<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>