Effect preview:

After the information input is completed, click “Confirm generation” to generate the picture, and the “Save” && “Cancel” button will appear. Click “Save” to save to the album, and cancel to return to the editing page:

Saved image effect:This is very simple, mainly using wechat small program canvas implementation, specific code:

card.wxml:

<view class="content">
  <scroll-view scroll-y="true" style="height: 1334rpx;" 
    bindscroll="scroll" scroll-into-view="{{toView}}" scroll-top="{{scrollTop}}">

    <! -- Template Generation popup -->
    <view class="canvas-content">
      <view class="con">
        <canvas canvas-id='myCanvas' class='canvas'></canvas>
        <view class="info">
          <! - industry -- -- >
          <view class="show-post-text">{{upost}}</view>
          <! -- name -- -- >
          <view class="show-name-text">{{uname}}</view>
          <! -- Contact number -->
          <view class="show-company-text">{{ucompany}}</view>
        </view>
      </view>
      <view class="canvas-bottom" hidden="{{isHidde}}">
        <view class="btn-save" bindtap="saveImg">save</view>
        <view class="btn-close" bindtap="closeDialog">cancel</view>
      </view>
    </view>

    <! -- Edit area -->
    <view class="edit-tips">Editor:</view>
    <view class="form-container">
      <view class="show-name item">
        <label class="name-label">Name:</label>
        <input type="text" v-model="name" placeholder="" bindinput="onchangeName" class="input" />
      </view>
      <view class="line"></view>
      <view class="show-company item">
        <label class="company-name-label">Contact Number:</label>
        <input type="text" v-model="company" placeholder="" bindinput="onchangeCompany" class="input" />
      </view>
      <view class="line"></view>
      <view class="show-post item">
        <label class="name-post-label">Industry:</label>
        <input type="text" v-model="post" placeholder="" bindinput="onchangePost" class="input" />
      </view>
    </view>

    <view class="create-btn">
      <button bindtap="createImg" hidden="{{hiddeButton}}" class="btn">Determine the generated</button>
    </view>
  </scroll-view>
  
</view>
Copy the code

Card.js :(main logical function)

There are basically written comments, not clear can see the official documentation of the API

Page({
  data: {
    imgUrl: "http://pic.51yuansu.com/backgd/cover/00/40/00/5be62bbb6ac3f.jpg! /fw/780/quality/90/unsharp/true/compress/true",
    isHidde: true,
    hiddeButton: false,
    ucompany: ' ',
    uname: ' ',
    upost:' '
  },

  /* Listen for input changes */
  onchangeCompany(e) {
    var that = this;
    that.setData({
      ucompany: e.detail.value,
    })
  },
  onchangePost(e) {
    var that = this;
    that.setData({
      upost:e.detail.value,
    })
  },
  onchangeName(e) {
    var that = this;
    that.setData({
      uname: e.detail.value
    })
    // console.log(" Enter to listen for changes: "+ this.data.uname);
  },
  scrollToTop() {
    this.setAction({
      scrollTop: 0})},/* Initializes the loading display */OnLoad: function (options) {// Convert network images to local wX.getImageInfo({
      src: this.data.imgUrl,
      success: (res) => {
        this.setData({
          imgUrl: res.path
        })
        this.getcanvas(a); }})},/* Generate the image */
  createImg() {
    this.getcanvas(a); this.setData({
      isHidde: false,
      // hiddeButton: true,
      ucompany: ' ',
      uname: ' ',
      upost: ' '})},/* Draw canvas content */
  getcanvas() {
    let that = this;
    let ctx = wx.createCanvasContext('myCanvas');
    // ctx.setFillStyle('red');    
    let metrics = ctx.measureText(that.data.ucompany); Let name = CTX.measureText(that.data.uname); // Get the font width let RPX =1;
    wx.getSystemInfo({
      success(res) {
        rpx = res.windowWidth / 375; 

      },
    })
    ctx.drawImage(this.data.imgUrl.0.0.300 * rpx, 460* rpx); // Draw the industry text CTX.setFontSize(20 * rpx);
        ctx.setFillStyle('#fff');
        ctx.setTextAlign('center');
        ctx.fillText(that.data.upost.60 * rpx,30* rpx); // Parameters: text content, x, y // Draw the name text CTX.setFontSize(40 * rpx);
        ctx.setFillStyle('#fff');
        ctx.setTextAlign('center');
        ctx.fillText(that.data.uname.150 * rpx, 80* rpx); // Draw the contact number CTX.setFontSize(20 * rpx);
        ctx.setFillStyle('#fff');
        ctx.setTextAlign('left')
        ctx.fillText(that.data.ucompany.80 * rpx, 120 * rpx);
        ctx.draw(a); // Add the content tocanvas},/* Save the image */
  saveImg() {
    wx.showLoading({
      title: 'Saving',
      mask: true,
    })
    wx.canvasToTempFilePath({
      canvasId: 'myCanvas',
      success: (res) => {
        wx.hideLoading(a); wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success(res) {
            wx.showToast({
              title: 'Saved successfully! ',})}})}}); },/* Unsave */
  closeDialog() {
    wx.showToast({
      title: 'Unsaved! '}); this.setData({
      isHidde: true,
    });
    this.resetCanvas(a); },/* Resets the image template content */
  resetCanvas() {
    this.setData({
      hiddeButton: false,
    });
    this.getcanvas(a); }})Copy the code

In the event processing, setData is used to set the value of the variable to the input information:

    that.setData({
      ucompany: e.detail.value,
    })
Copy the code

Others are similar.

card.wxss:

.canvas-bottom {
  display: flex;
  flex-direction: row;
  margin-top: 70rpx;
  width: auto;
  box-sizing: border-box;
  justify-content: space-around;
}

.btn-save {
  text-align: center;
  border-radius: 30rpx;
  /* margin-left: 50rpx; * /
  width: 130rpx;
  font-size: 14px;
  padding: 13rpx 40rpx;
  /* background-color: #2fa5ff; * /
  background-color:#7F7AA6 ;
  color: #fff;
}

.btn-close {
  text-align: center;
  border-radius: 30rpx;
  width: 130rpx;
  /* margin-right: 50rpx; * /
  font-size: 14px;
  padding: 13rpx 40rpx;
  border: 1rpx solid #7F7AA6 ;
  color: #7F7AA6 ;
}

.create-btn {
  width: 100%;
  height: 60rpx;
  font-size: 14px;
  background-color: #7F7AA6 ;
}

.content {
  height: 100vh;
}

.canvas-content {
  background: #ffffff;
  position: relative;
  margin: 0 auto;
}

.canvas-content .con {
  /* background: #AE0001; * /
  width: 690rpx;
  position: relative;
  margin: 0 auto;
}

.canvas {
  margin: 15rpx auto;
}


.canvas-content {
  width: 750rpx;
  padding-bottom: 60rpx;
}

.info {
  position: absolute;
  left: 0rpx;
  top: 0rpx;
  height: 300rpx;
}

.show-name-text {
  font-size: 72px;
  color: #fff;
  width: 600rpx;
  text-align: center;
}
.show-post-text {
  font-size: 32px;
  color: #fff;
  width: 600rpx;
  text-align: center;
}

.choose {
  width: 100vw;
  margin-top: 100rpx;
  display: flex;
  justify-content: center;
}

.choose .choose-btn {
  width: 60%;
  margin-top: 30rpx;
  display: flex;
  justify-content: space-around;
}

.choose .choose-btn .abtn..bbtn {
  margin-right: 20rpx;
  font-size: 16px;
  color: # 424242;
  text-align: center;
}

.choose .choose-btn .abtn {
  border: 1rpx solid #7F7AA6 ;
  color: #7F7AA6 ;
}

.edit-tips {
  height: 160rpx;
  background: #eee;
  padding-left: 30rpx;
  font-size: 24rpx;
  color: # 969696;
  line-height: 240rpx;
}

.edit-canvas {
  width: 750rpx;
  height: 300rpx;
  text-align: center;
  line-height: 300rpx;
  background: #F80101;
}

.line {
  width: 100%;
  height: 1rpx;
}

.company-text {
  line-height: 60rpx;
  height: 60rpx;
}

.show-company-text {
  line-height: 60rpx;
  height: 60rpx;
  padding-left: 30rpx;
  color: #fff;
  width: 750rpx;
  text-align: left;
  font-size: 40rpx;
}

.input {
  width: 440rpx;
  height:70rpx;
  margin-top: 15rpx;
  padding-left: 30rpx;
  border-radius: 44rpx;
  background: #f5f5f5; 
  display: inline-block;
}

.company-name-label..name-post-label {
  float: left;
  margin-right: 30rpx;
  color: # 747474;
}

.name-label..post-label {
  float: left;
  color:  # 747474;
  width: 160rpx;
}

.show-post{
  background: #fff;
  height: 80rpx;
  padding-left: 30rpx;
  line-height: 80rpx;
}

.show-company {
  background: #fff;
  height: 80rpx;
  padding-left: 30rpx;
  line-height: 80rpx;
}

.show-name {
  padding-left: 30rpx;
  background: #fff;
  height: 80rpx;
  line-height: 80rpx;
}

.show-post {
  padding-left: 30rpx;
  background: #fff;
  height: 80rpx;
  line-height: 80rpx;
}

.create-btn {
  height: 80rpx;
  text-align: center;
  font-size: 32rpx;
  color: #fff;
  text-align: center;
  border-radius: 0rpx;
  background:#7F7AA6 ;
  margin-top: 160rpx;
  width: 100%;
  position: fixed;
  bottom: 0;
  left: 0;
}

.create-btn .btn {
  text-align: center;
  color: #fff;
  font-size: 16px;
  background: none;
}
Copy the code

card.json:

{"usingComponents": {}, "navigationBarTitleText":" Template editing "}Copy the code

Because the picture network brought, the need to set up not to examine the legitimate domain name, purely weekend fool around!

Source code download:

Github.com/Lydever/wx-…