Das Uniapp-Applet verwendet Canvas, um Inhalte zu zeichnen und im lokalen Fotoalbum zu speichern

Anforderungen: Die entsprechenden Zertifikate werden automatisch für verschiedene Benutzer generiert und die Zertifikate können heruntergeladen werden (nach dem Herunterladen erhalten Sie ein Bild). Um diese Funktion zu realisieren, müssen Sie den dynamisch generierten Inhalt mithilfe der Hilfe in die Seite zeichnen der Leinwand, und realisieren Sie dann die Download-Funktion.

1. HTML-Code

<view class="certify-main">
  <canvas type="2d" id="myCanvas" style="width: 375px; height: 550px;background-color: #fff;" />
  <view class="download" @click="download">下载证书</view>
</view>

Die Seite ist sehr einfach gehalten und enthält nur eine Leinwand und einen Download-Button.

2. js-Code

// 所需数据
data() {
  return {
    name: "",
    year: "",
    month: "",
    day: "",
    beforeName: "",
    textCanvas: null,
    certificateNo:'',
    certQrCode:'', // 后台返回的二维码地址
  };
},

// 所需方法
methods(){
  // 从后台获取信息(以下代码我做了封装,你们直接正常请求接口获取数据就行,可以忽略)
  getCurrentOrg() {
    let opts = {
      url: url,  // url是接口地址
      method: "get",
    };
    let param = {}; // 参数
    request
      .httpTokenRequest(opts, param)
      .then((data) => {
        if (data && data.data && data.data.data) { 
          // 将获取到的数据赋值给对应字段
          const msg = data.data.data;
          if (msg.updateTime) {
            this.year = msg.updateTime.substring(0, 4)
            this.month = msg.updateTime.substring(5, 7)
            this.day = msg.updateTime.substring(8, 10)
          }
          this.beforeName = msg.snmsPrefix || "";
          this.name = msg.orgName;
          this.certificateNo = msg.certCode
          this.certQrCode = msg.certQrCode
          // 调用canvas绘制内容的方法
          this.drawCanvas()
        }
      })
      .catch((err) => {
        console.log(err);
        this.$refs.uToast.show({
          title: "数据异常或不存在",
          type: "warning",
          duration: "2300",
        });
      });
  },
  // 下载证书的方法
  download() {
    // 指定 this 指向
    let that = this;
    // 在微信中保存canvas为图片到本地,要通过canvas 实例的参数进行设置
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: that.textCanvas.width, // 设置画布宽度
      height: that.textCanvas.height, // 设置画布高度
      destWidth: that.textCanvas.width, // 屏幕width像素密度设置
      destHeight: that.textCanvas.height, // 屏幕height像素密度设置
      canvas: that.textCanvas, // 这里是重点,获取实例的时候保存为全局变量就行了
      complete(res) {
        console.log(res);
        // res.tempFilePath 返回的是临时地址 png 或者 jpg
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success() {
            uni.showToast({
              title: "保存成功",
              icon: "success",
            });
          },
          fail() {
            uni.showToast({
              title: "保存失败",
              icon: "error",
            });
          },
        });
      },
    });
  },
  drawCanvas() {
    // 指定this的指向
    let that = this;
    // uni-app 中,不管是小程序,app,h5 在获取元素实例时,都是统一的方法,只要获取元素的宽高
    uni
      .createSelectorQuery()
      .select("#myCanvas")
      .fields({ node: true, size: true })
      .exec((res) => {
        console.log(res);
        // 获取设备设备像素比
        const dpr = uni.getSystemInfoSync().pixelRatio;
        // 微信小程序绘制
        let textCanvas = (that.textCanvas = res[0].node); // 获取元素实例
        textCanvas.width = res[0].width * dpr; // 设置canvas像素宽
        textCanvas.height = res[0].height * dpr; // 设置canvas像素高
        let textCtx = textCanvas.getContext("2d"); // 创建二维绘图
        textCtx.clearRect(0, 0, res[0].width, res[0].height); // 设置画布大小
        textCtx.beginPath(); // 创建一条新的路劲
        textCtx.scale(dpr, dpr); // 设置x,y缩放(这里作用不大,,没效果)
        // 这里开始绘制canvas内容,绘制的过程当中,不知道是小程序的问题,还是什么问题在绘制有背景图片的内容时,
        // 文字内容必须要延迟绘制,也就是要定时器延迟一定时间才能绘制,要不然就会将文字覆盖在图片下方。
        // 图片的绘制(这里将此图片作为背景图的,图片不能带底色,即透明的,方便在上面写字绘图)
        const tx = textCanvas.createImage();
        tx.src = "https://test.xxxx.com/pic/new_certify.png"; // 线上地址或者本地地址都可以
        tx.onload = () => {
          textCtx.drawImage(
            tx,
            5,
            20,
            res[0].width-10,
            res[0].height-20
          ); // 参数从左到右说明, 图片文件,x轴开始位置,y轴开始位置,x轴结束位置,y轴结束位置
        };
        // 文字设置
        textCtx.fillStyle = "#333"; // 文字颜色
        textCtx.font = "bold 12px MicrosoftYaHei"; // 字体样式 设置加粗("normal bold 16px sans-serif");
        textCtx.fillText(this.name, 102, 203); // 设置文字内容, x轴位置,y轴位置
        textCtx.fillText(this.year, 111, 230); // 设置文字内容, x轴位置,y轴位置
        textCtx.fillText(this.month, 180, 230); // 设置文字内容, x轴位置,y轴位置
        textCtx.fillText(this.day, 230, 230); // 设置文字内容, x轴位置,y轴位置
        textCtx.fillText(this.beforeName, 168, 296); // 设置文字内容, x轴位置,y轴位置
        textCtx.fillStyle = "#003E8A";
        textCtx.font = "10px MicrosoftYaHei";
        textCtx.fillText(this.certificateNo, 186, 466); // 设置文字内容, x轴位置,y轴位置
        // 二维码设置
        const tx1 = textCanvas.createImage();
        tx1.src = this.certQrCode
        tx1.onload = () => {
          textCtx.drawImage(
            tx1,
            154,
            380,
            65,
            65
          ); // 参数从左到右说明, 图片文件,x轴开始位置,y轴开始位置,x轴结束位置,y轴结束位置
        };
      });
  },
}

3. Anzeige von Renderings

Hinweis: Ich habe vergessen, den Stil der Zertifikatsnummer im Bild unten zu ändern. Einige Informationen sind mosaikartig, da sie den Datenschutz des Projekts betreffen, haben jedoch keinen Einfluss auf den Gesamteffekt (der schwarze Text + der QR-Code + die Zertifikatsnummer sind dynamisch und die Der Rest des Textes ist das Hintergrundbild. In sich geschlossen)

 

おすすめ

転載: blog.csdn.net/JJ_Smilewang/article/details/128728269