• 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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171

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

      if(e.scene){//分享的小程序二维码,扫码进入
    	  let scene = decodeURIComponent(e.scene)
    	  let arr = scene.split("&")
    	  projectId = arr[0].split("=")[1]
      }else{ // 通过微信的分享朋友的卡片进入
    	  projectId = e.projectId || ''
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    Java 初学者必备核心基础知识有哪些?
    24位ADC芯片AD7190讲解和代码编写(基于STM32模板的硬件软件SPI)
    Unreal Engine 学习笔记 (1)—— 日夜交替
    Docker基础学习
    【机器学习】阿里云天池竞赛——工业蒸汽量预测(5)
    算法导论第15、16章习题—动态规划、贪心算法
    异常值检测!最佳统计方法实践(代码实现)!⛵
    Golang 中对 json 的优雅处理
    css 样式 使用变量
    [ LeetCode ] 题刷刷(Python)-第58题:最后一个单词的长度
  • 原文地址:https://blog.csdn.net/rhcjqmm666/article/details/134059943