qrcodejs2+html2canvas 生成二维码和海报踩坑记录

3,271 阅读1分钟

插件

  • qrcode2
  • html2canvas(修改版)

image.png

链接:pan.baidu.com/s/1MZLo8WEA… 提取码:ksvc

效果展示

image.png

安装qrcodejs2

yarn add qrcodejs2 -S

引入html2canvas

在项目js入口文件引入html2canvas,如下图

image.png

HTML部分

<template>
  <div id="app">
    <!-- 按钮 -->
    <button @click="showDiglog">点我</button>
    <!-- 海报模板 -->
    <div ref="dialog" class="dialog">
      <img
        id="bg"
        src="https://res.miaocode.com/dragon-boat/posterimgbg.jpg"
        alt=""
      />
      <img
        id="head"
        src="https://res.miaocode.com/54efb4cd-0d7a-4dd3-af8f-5e7f41d39158.jpg"
      />
      <div id="qrcode" ref="qrcode"></div>
    </div>
    <!-- 生成的海报弹框和图片 -->
    <div
      v-show="dialogVisible"
      class="dialog-layer"
      @click="hideDialog($event)"
    >
      <img ref="saveImage" class="save-image" src="" alt="" />
    </div>
  </div>
</template>

Script部分

<script>
import QRCode from 'qrcodejs2';

export default {
  name: 'SaveImage',
  // eslint-disable-next-line vue/no-unused-components
  components: { QRCode },
  data() {
    return {
      dialogVisible: false,
      link: 'https://www.baidu.com/',
    };
  },
  mounted() {
    // 清空二维码
    this.$refs.qrcode.innerHTML = '';
    // 生成二维码
    this.$nextTick(function () {
      // 根据html的fontSize动态计算二维码宽高
      const htmlFontSize = getComputedStyle(window.document.documentElement)[
        'font-size'
      ];
      const w = parseInt(htmlFontSize) * 3;
      const h = parseInt(htmlFontSize) * 3;
      this.qrcode(w, h, this.link, 'canvas');
    });
  },
  methods: {
    /**
     * @description 生成二维码
     * @param  {number} qWidth  宽度
     * @param  {number} qHeight  高度
     * @param  {string} qText  二维码内容(跳转连接)
     * @param  {string} qRender 渲染方式(有两种方式 table和canvas,默认是canvas)
     */
    qrcode(qWidth, qHeight, qText, qRender) {
      new QRCode(this.$refs.qrcode, {
        width: qWidth,
        height: qHeight,
        text: qText,
        render: qRender,
        correctLevel: QRCode.CorrectLevel.L,
      });
    },
    // 显示弹框
    showDiglog() {
      //二维码初始化 点击一次添加一个二维码
      const dialog = this.$refs.dialog;
      const saveImage = this.$refs.saveImage;
      html2canvas(dialog, {
        useCORS: true,
        logging: true,
        width: dialog.offsetWidth,
        height: dialog.offsetHeight,
        scale: window.devicePixelRatio || 1,
      }).then(canvas => {
        const dataUrl = canvas.toDataURL('image/png', 1.0);
        console.log('dataUrl', dataUrl);
        saveImage.setAttribute('src', dataUrl);
        this.dialogVisible = true;
      });
    },
    // 隐藏弹框
    hideDialog(e) {
      const saveImage = this.$refs.saveImage;
      if (saveImage) {
        //判断如果不是当前节点就隐藏弹窗
        if (!saveImage.contains(e.target)) {
          this.dialogVisible = false;
        }
      }
    },
  },
};
</script>

Style部分

<style scoped lang="scss">
.dialog {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 15rem;
  height: 26.68rem;
  opacity: 0;
  #bg {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
  }
  #head {
    width: 3.2rem;
    height: 3.2rem;
    position: absolute;
    left: 50%;
    margin-left: -1.6rem;
    bottom: 11rem;
    border-radius: 1.5rem;
  }
  #qrcode {
    position: absolute;
    bottom: 2rem;
    right: 1.8rem;
    border-radius: 0.2rem;
    padding: 0.2rem;
    background: white;
    display: flex;
    align-items: center;
    justify-content: center;
    transform: scale(0.8);
  }
}

.dialog-layer {
  width: 100%;
  height: 100%;
  position: fixed;
  left: 0;
  top: 0;
  background: rgba(0, 0, 0, 0.75);
  z-index: 10;
  .save-image {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 15rem;
    height: 26.68rem;
    z-index: 100;
  }
}
</style>

注意事项

  • 模板不能使用背景图片
  • 定位元素居中使用transform无效,居中可以使用margin-left: -50%