Canvas generates posters and dynamically calculates the size of the image to adapt to the height of the poster.

1.js code

// pages/nav/nav.js
Page({

  /**
   * Initial data of the page
   */
  data: {
    nav: ['All', 'Fruits and Vegetables', 'Home Appliances', 'Books', 'Daily Necessities', 'Test', 'Stand Test', ' Still a test'],
    // current project
    current: 2,
    //Scroll bar scroll distance
    scrollLeft: 0,
    // Window width
    windowWidth: 0,
    canvasImg: '',
    share: false, //Whether to share
    base64Qr: '', //The base64 picture obtained by the QR code interface
    drawing: false, //Whether to draw the poster
    loading: false, //Whether to draw the poster when clicking to share
    sourceUrl1: "https://purchasing-miniapp-cdn.a2milk.com/a2/img/invitenow/share1.png", //Internet picture
    sourceUrl: "http://campaigncdn.herdsric.com/a2/adjust/100.jpg", //Internet pictures
    sizeHeight: '',
    newheight: '',
    pixelRatio: '',
    windowH: '',
    windowW: '',
    tempNum: '',
    testTop: ''
  },

  onLoad: function (options) {
    //Set title
    wx.setNavigationBarTitle({
      title: 'Navigation Bar Case',
    });

    // Get the form width
    wx.getSystemInfo({
      success: (result) => {
        this.setData({
          windowW: result.windowWidth,
          windowH: result.windowHeight,
          windowWidth: result.windowWidth,
          pixelRatio: result.pixelRatio
        })
      },
    })
    // this.shareShow()
  },
  //Display mask layer
  shareShow() {
    this.setData({
      canvasImg: '',
      drawing: true
    })
    setTimeout(() => {
      this.setShareCanvas(); // Share drawing
    }, 800)

    // wx.showLoading({
    // title: 'Poster generation',
    // })
  },

  setShareCanvas() {
    const that = this;
    const query = wx.createSelectorQuery();
    query.select('#shareCanvas')
      .fields({
        node: true,
        size: true
      }).exec((res) => {
        const canvas = res[0].node //Get the canvas object
        that.setData({ //The canvas object is saved here because this object is used to save photos below.
          canvas
        })
        const ctx = canvas.getContext('2d') //Returns the environment used for drawing on the canvas
        const dpr = that.data.pixelRatio //Get the device pixel ratio
        canvas.width = res[0].width * dpr //Scale the canvas
        canvas.height = res[0].height * dpr
        ctx.scale(dpr, dpr)
        //Set the background to white
        ctx.fillStyle = "#fff";
        new Promise(function (resolve) {
          //2. Draw pictures and text
          const imggood = canvas.createImage()
          imggood.src = that.data.sourceUrl
          imggood.onload = (e) => {
            var newheight = that.fitSize(240) * imggood.height / imggood.width
            that.setData({
              newheight: newheight
            })
            if (newheight > that.fitSize(240)) {
              newheight = that.fitSize(240)
              that.setData({
                heightNew: 1,
                newheight: newheight
              })
              console.log(that.data.heightNew, newheight, '00000')
            }
            let cutHeight = imggood.height
            if (imggood.height > imggood.width) {
              cutHeight = imggood.width
            }
            const tempNum = 20
            that.setData({
              tempNum: tempNum
            })
            ctx.fillRect(0, 0, that.fitSize(275), that.fitSize(78) + newheight + tempNum + that.fitSize(48) + tempNum + that.fitSize(48))
            console.log(that.fitSize(78) + newheight + tempNum + that.fitSize(48) + tempNum + that.fitSize(48), '0')
            that.setData({
              sizeHeight: that.fitSize(78) + newheight + tempNum + that.fitSize(48) + tempNum + that.fitSize(48)
            })
            ctx.drawImage(imggood, 0, 0, imggood.width, cutHeight, that.fitSize(17), that.fitSize(78), that.fitSize(240), newheight);
            let str = 'Get a2? brand materials and unlock exclusive membership benefits! '
            let chr = str.split("");
            let temp = "";
            let row = [];
            ctx.font = `${parseInt(that.fitSize(12))}px FZabj-small`;
            ctx.fillStyle = '#4E4E4E';
            for (let a = 0; a < chr.length; a + + ) {
              if (ctx.measureText(temp).width < (that.fitSize(136))) {
                temp + = chr[a];
              } else {
                a--;
                row.push(temp);
                temp = "";
              }
            }
            row.push(temp);
            if (row. length > 2) {
              let rowCut = row.slice(0, 2);
              let rowPart = rowCut[1];
              let test = "";
              let empty = [];
              for (let a = 0; a < rowPart.length; a + + ) {
                if (ctx.measureText(test).width < (that.fitSize(140))) {
                  test + = rowPart[a];
                } else {
                  break;
                }
              }
              empty.push(test);
              let group = empty[0] + "..." //Only two lines are displayed here, and the excess is represented by...
              rowCut.splice(1, 1, group);
              row = rowCut;
            }
            let testTop = 13
            that.setData({
              testTop: testTop
            })
            //Modify the distance between the text and the image
            for (let b = 0; b < row.length; b + + ) {
              ctx.fillText(row[b], that.fitSize(32), that.fitSize(78) + newheight + that.data.tempNum + b * 17 + that.fitSize(testTop));
            }
            resolve(true);
          }
        }).then(function () {
          return new Promise(function (resolve) {
            const imgbg = canvas.createImage()
            imgbg.src = 'https://purchasing-miniapp-cdn.a2milk.com/a2/img/adjust/hbwz1.png'
            imgbg.onload = (e) => {
              ctx.drawImage(imgbg, that.fitSize(64), that.fitSize(22), that.fitSize(150), that.fitSize(39))
              resolve(true);
            }
          })
        }).then(function () {
          return new Promise(function (resolve) {
            //Draw mini program QR code picture
            const imgqrcode = canvas.createImage()
            imgqrcode.src = 'https://campaigncdn.herdsric.com/a2/adjust/qrCode.jpg'
            imgqrcode.onload = (e) => {
              console.log(that.data.newheight)
              //Draw QR code
              ctx.drawImage(imgqrcode, that.fitSize(192), that.fitSize(78) + that.data.newheight + that.data.testTop, that.fitSize(48), that.fitSize(48))
              resolve(true);
            }
          })
        }).then(function () {
          return new Promise(function (resolve) {
            const radius = 6; //Set the radius to 10px
            ctx.moveTo(that.fitSize(17), that.fitSize(78))
            ctx.lineTo(that.fitSize(257), that.fitSize(78))
            let boxLine = that.fitSize(78) + that.fitSize(48) + that.data.newheight + that.data.testTop + that.fitSize(15)
            //The arc of the lower right corner
            ctx.arcTo(that.fitSize(257), boxLine, that.fitSize(78), boxLine, radius); // Draw an arc path from the starting point to the end point
            ctx.lineTo(that.fitSize(257) - radius, boxLine)
            //The arc of the lower left corner
            ctx.arcTo(that.fitSize(17), boxLine, that.fitSize(17), 100, radius); // Draw an arc path from the starting point to the end point
            ctx.lineTo(that.fitSize(17), boxLine - radius)
            ctx.lineTo(that.fitSize(17), that.fitSize(78))
            //Set the style and color of the border
            ctx.lineWidth = 0.2; // border width
            ctx.strokeStyle = 'gray'; // Border color

            //Set shadow properties and draw borders
            ctx.shadowColor = '#000'; // Shadow color
            ctx.shadowBlur = 10; // Shadow blur radius
            ctx.shadowOffsetX = -5; // Shadow horizontal offset
            ctx.shadowOffsetY = 6; // Shadow vertical offset
            ctx.stroke()
            resolve(true);
          })
        }).then(function () {
          return new Promise(function (resolve) {
            //Draw bottom text
            const imgWz = canvas.createImage()
            imgWz.src = 'https://purchasing-miniapp-cdn.a2milk.com/a2/img/adjust/hbwz2.png'
            imgWz.onload = (e) => {
              ctx.drawImage(imgWz, that.fitSize(80), that.fitSize(78) + that.data.newheight + 4 + that.data.testTop + that.fitSize(53) + that.data.tempNum, that.fitSize (115.6), that.fitSize(28.8))
              resolve(true);
            }
          })
        }).then(function () {
          return new Promise(function (resolve) {
            console.log('Drawing completed, converted into picture', canvas)
            that.transferCanvasToImage(canvas)
            resolve(true);
          })
        }).catch((err) => {
          that.setData({

          })
        })
      })
  },

  transferCanvasToImage(canvas) {
    const that = this;
    wx.canvasToTempFilePath({
      canvas: canvas,
      x: 0,
      y: 0,
      width: (that.fitSize(275)),
      height: (that.data.sizeHeight),
      success(res) {
        console.log('canvas sharing image address', res.tempFilePath)
        that.data.loading & amp; & amp; wx.hideLoading()
        that.setData({
          canvasImg: res.tempFilePath
        })
        wx.hideLoading()
      },
      fail: (err) => {
        console.log(err, 'Conversion failed')
      }
    })
  },

  //Click on the image to preview, long press to save and share the image
  preImg: function (e) {
    var img = this.data.canvasImg
    wx.previewImage({
      current: img, // http link of the currently displayed image
      urls: [img] // List of image http links that need to be previewed
    })
  },

  fitSize(coordinate) {
    let that = this;
    let windowW = that.data.windowW; //This windowWidth refers to the width of the device, which can be obtained from onLoad monitoring page loading.
    let v = 375 / windowW; //375 is the size of the design draft. The obtained v value is: the proportional relationship between the design draft and the width of the device. It can also be understood as a multiple of enlargement or reduction based on the size of the design draft.
    return coordinate / v; //Returns the current coordinate value or the ratio of size to v
  },


})

2.wxml code

 <view class="canvas-box" wx:if="{<!-- -->{drawing}}">
    <view class="card-cancle" >
      <canvas type="2d" id="shareCanvas" canvas-id="Canvas" style="width: {<!-- -->{windowW}}px; height: {<! -- -->{ windowH }}px;position:fixed;top:9999px"></canvas>
      <image src="{<!-- -->{canvasImg}}" bindtap="preImg" show-menu-by-longpress class="share-image" mode="widthFix" ></image>
    </view>
  </view>
  <view bindtap="shareShow">Generate poster</view>

3.wxss code

.canvas-box{
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  z-index: 10;
  background: rgba(0, 0, 0, .7);

}
.card-cancle {
  /* margin-top: 276rpx; */
  width: 540rpx;
  height: 844rpx;
  /* background: #FFFFFF; */
  border-radius: 8rpx;
    margin: 0 auto;
    margin-top: 310rpx;
}
.share-image {
  width: 540rpx;
  height: 900rpx;

  padding: 1px;
  /* margin-top: 90px; */
}