vue生成分享海报

最近的项目里面涉及到分享海报的问题,今天就给大家分享一下,自己中间也遇到也很多问题,中间也有很多不足的地方,有什么问题,欢迎大家指教。
效果图
vue生成分享海报_第1张图片
实现原理
先用 QRCode 生成二维码 canvas,然后用 html2canvas 合成整张海报并转成 base64
实现步骤:
1.安装QRCode和html2canvas

npm i qrcode
npm i html2canvas

2.在页面中引用

import QRCode from "qrcode";
import html2canvas from "html2canvas";

3.HTML代码

<template>
  <div>
    <div class="top">
      <div @click="getimg">
        <span>分享</span>
        <p>海报</p>
      </div>
    </div>
    <div class="ypl-flex">
      <div class="invitePosterPage flex">
        <div v-if="posterDataUrl">
          <van-popup v-model="show">
            <div class="oter">
              <img :src="posterDataUrl" class="poster-bg" alt="邀请海报" />
            </div>
          </van-popup>
        </div>
        <div v-else id="poster" class="flex-row">
          <img class="poster-bg" src="../../assets/images/timg.jpg" alt="邀请海报背景" />
          <div class="qqqqq">
            <div class="title ">{{canvasImg.title}}{{canvasImg.content}}</div>
            <img class="title-img" :src="canvasImg.cover" alt />
            <canvas class="qr" id="qrCode-canvas"></canvas>
            <div class="txt">长按识别二维码</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

4.js代码

<script>
/**
 * 这是邀请海报组件
 */
import QRCode from "qrcode";
import html2canvas from "html2canvas";

export default {
  name: "Poster",
  props: ["canvasImg"],
  data() {
    return {
      posterDataUrl: "",
      qrCodeUrl: window.location.href,
      show: false
    };
  },
  mounted() {
  },
  methods: {
    getimg() {
      this.show = true;
      this.createQRCode();
    },
    createQRCode() {
      //先用 QRCode 生成二维码 canvas,然后用 html2canvas 合成整张海报并转成 base64 显示出来
      let canvas = document.getElementById("qrCode-canvas");
      QRCode.toCanvas(canvas, this.qrCodeUrl, error => {
        if (error) {
          console.log(error);
        } else {
          canvas.style.width = "2.3rem";
          canvas.style.height = "2.3rem";
          let poster = document.getElementById("poster");
          html2canvas(poster,{useCORS:true,backgroundColor:null,
          taintTest: true, // 在渲染前测试图片
          timeout: 500 // 加载延时
          }).then(canvas => {
            this.posterDataUrl = canvas.toDataURL();
          });
        }
      });
    }
  }
};
</script>

5.css代码

<style >
.ypl-flex {
  text-align: center;
  position: relative;
  /* height: 100vh; */
  margin: 0 auto;
  vertical-align: bottom;
  z-index: 2;
}
.invitePosterPage {
  width: 100%;
  text-align: center;
  position: absolute;
  /* bottom: 100px; */
}
.invitePosterPage > img {
  width: 100%;
  text-align: center;
  vertical-align: bottom;
}
.flex {
  width: 100%;
  text-align: center;
  margin: 0 auto;
}
.oter {
  width: 100%;
  margin: 0 auto;
}
.oter > img {
  width: 100%;
  height: 8rem;
  vertical-align: bottom;
}
.flex-row {
  width: 80%;
  margin: 0 auto;
  /* position: absolute; */
  position: fixed;
  bottom: -2000px;
}
.flex-row > img {
  width: 100%;
  height: 8rem;
  vertical-align: bottom;
}
.qr {
  width: 2rem;
  height: 2rem;
}
.qqqqq {
  margin: 0 anto;
  position: absolute;
  left: 0;
  right: 0;
  bottom: .5rem;
}
.qqqqq .txt {
  font-size: 0.24rem;
  color: #b39834;
  margin-top: 0.5rem;
}
.qqqqq .title {
  margin-bottom: .6rem;
  color: #fff;
  font-size: .26rem;
  padding: .3rem;
}
.title-img {
  width: 70%;
  height: 2rem;
  margin-bottom: .6rem;
}
.van-popup--center {
  width: 80%;
}
.top {
  position: fixed;
  bottom: .9rem;
  right: 0.4rem;
  height: 0.6rem;
  width: 0.6rem;
  z-index: 3;
}
.top > div {
  height: 0.6rem;
  width: 0.6rem;
  background: #c7a470;
  border-radius: 50%;
  font-size: 10px;
  text-align: center;
  padding: 2px;
  color: #fff;
}
.van-popup {
  background-color: transparent;
}
</style>

期间也遇到很多的坑
1.动态图片无法加载:如果要合成的容器里面有动态的图片(通过 URL 来显示的图片),需要开启图片跨域才能正常合成。首先是图片服务器要开启跨域访问,然后就是 html2canvas 要开启跨域功能,二者缺一不可。
2.微信 2.2.0 版本之前,试验过 display : none; height : 1px 等常用的隐藏元素方法,都不能准确的读取 canvas 中的元素内容,因此使用将显示元素移动到显示区域外的做法,将 canvas 隐藏起来


.canWrap{
    /* 该处必须使用绝对定位,并且定位到显示区域外面,如果 canvas 的大小显示不全,则保存到 image 元素中的大小也是不准确的 */
    position: fixed;
    bottom: -2000rpx;
    overflow: visible;
    }

以上代码直接复制就可以用,有问题欢迎留言!

你可能感兴趣的:(vue项目)