canvas画布生成图片并下载

前端页面代码

<template>
  <div class="shareImg">
    <!-- <Header :title="title"></Header> -->
    <div class="share">
      <img :src="image" class="img" alt="" />
      <canvas id="mycanvas" class="my-canvas"></canvas>
    </div>
    <div class="tips flex-c-c" v-if="!show">
      <span>(长按保存图片)</span>
    </div>
    <div class="m-t10" v-if="show">
      <van-button type="info" @click="dowload">保存图片</van-button>
    </div>
  </div>
</template>

<script>
// import Header from "../components/Header";
import { itemextendQrcode } from "../api/Home";
export default {
  data() {
    return {
      title: "分享图",
      image: "",
      QRcode: "",
      item: {},
      show: true
    };
  },
  components: {
    // Header
  },
  created() {
    this.$LoadingToast("数据加载中");
    if (this.$store.state.status.envType === "xcx") {
      this.show = false;
    }
    if (this.$route.query.item) {
      this.item = JSON.parse(this.$route.query.item);
    }
  },
  mounted() {
    this.itemextendQrcode();
  },
  methods: {
    itemextendQrcode() {//调接口生成太阳码的二进制数据流,这个前端自己做不了,因为需要调用微信的接口,接口中有个参数存在有效期
      let user = JSON.parse(localStorage.getItem("user"));
      itemextendQrcode({
        pageStr: "pages/toggleLogin/toggleLogin",
        scene: `projectId=${this.item.id}&shareId=${user.uid}`
      }).then(res => {
        this.QRcode = `data:${res}`;
        this.drawPhoto();
        this.$clearToast();
      });
    },
    dowload() {
      let a = document.createElement("a");
      let event = new MouseEvent("click");
      a.download = "分享图.png";
      a.href = this.image;
      a.dispatchEvent(event);
    },
    drawtext(ctx, t, x, y, w) {
      //参数说明
      //ctx:canvas的 2d 对象,t:绘制的文字,x,y:文字坐标,w:文字最大宽度
      let a = t.length > 28 ? t.slice(0, 28) + "..." : t;
      let chr = a.split("");
      let temp = "";
      let row = [];
      ctx.fillStyle = "#1989fa";
      let multiple = (window.innerWidth / 375).toFixed(2);
      let size = `${18 * multiple}px`;
      ctx.font = `bold ${size} Arial`;
      for (let a = 0; a < chr.length; a++) {
        if (
          ctx.measureText(temp).width < w &&
          ctx.measureText(temp + chr[a]).width <= w
        ) {
          temp += chr[a];
        } else {
          row.push(temp);
          temp = chr[a];
        }
      }
      row.push(temp);
      for (let b = 0; b < row.length; b++) {
        ctx.fillText(row[b], x, y + (b + 1) * 25 * multiple); //每行字体y坐标间隔20
      }
    },
    drawPhoto: async function() {
      let multiple = (window.innerWidth / 375).toFixed(2); // 考虑不同设备的尺寸,直接通过目标设备宽度和375px宽度的比例作为展示效果的放大或者缩小
      const canvas = document.getElementById("mycanvas");
      const context = canvas.getContext("2d");
      const loadImage = src => {
        return new Promise((resolve, reject) => {
          const img = new Image();
          img.setAttribute("crossOrigin", "anonymous");
          img.onload = () => resolve(img);
          img.onerror = error => reject(error);
          img.src = src;
        });
      };
      try {
        const img1 = await loadImage(require("../assets/backShare.jpg"));
        const img2 = await loadImage(this.QRcode);
        const img3 = await loadImage(this.item.img);
        canvas.setAttribute("width", 316 * multiple);
        canvas.setAttribute("height", 560 * multiple);
        context.fillStyle = "lightblue";
        context.fillRect(0, 0, canvas.width, canvas.height);
        context.drawImage(img1, 0, 0, canvas.width, canvas.height);
        context.drawImage(
          img2,
          108 * multiple,
          80 * multiple,
          100 * multiple,
          100 * multiple
        );
        context.drawImage(
          img3,
          40 * multiple,
          230 * multiple,
          236 * multiple,
          236 * multiple
        );

        this.drawtext(
          context,
          this.item.name,
          35 * multiple,
          470 * multiple,
          265 * multiple
        );
        this.image = canvas.toDataURL("image/jpg", 1.0);
      } catch (error) {
        console.error("图片加载失败", error);
      }
    }
  }
};
</script>

<style lang="less" scoped>
.shareImg {
  margin: 55px auto 0;
}
.tips {
  color: #adacac;
  font-size: 14px;
}
.share {
  width: 100%;
  padding: 0px 30px;
}
.my-canvas {
  background-color: #fff;
  position: fixed;
  top: 1000000px;
  right: 10000px;
  z-index: 1;
}
.img {
  width: 100%;
  height: auto;
}
#mycanvas {
  border: 1px solid rgb(199, 198, 198);
}
</style>

小程序需要注意:同样传参是projectId = ‘12’,小程序的页面通过onShareAppMessage 分享和生成太阳码获取参数是不一样的

  if(e.scene){//分享的小程序二维码,扫码进入
	  let scene = decodeURIComponent(e.scene)
	  let arr = scene.split("&")
	  projectId = arr[0].split("=")[1]
  }else{ // 通过微信的分享朋友的卡片进入
	  projectId = e.projectId || ''
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值