微信小程序電子簽名實現


實現簽名方法就是使用canvas

<canvas canvas-id="firstCanvas" id='firstCanvas' bindtouchstart="bindtouchstart" bindtouchmove="bindtouchmove"></canvas>

<!-- 旋裝圖片 -->
<canvas canvas-id="saveImg" id='saveImg'></canvas>

<view class="clear" hidden="{{!sureBtn}}" bindtap='clear'>重新簽名</view>
<view class="save {{sureBtn?'sureBet':''}}" bindtap='export'>完成</view>

在canvas上綁定手指點擊事件和移動事件:

mymoa-2fn99.gif

上圖是想要實現的效果,
有幾個考慮的點:

  • 1、簽字區域和按鈕都是橫屏顯示的,這個首先想到的使用微信小程序的方法直接在json文件設置"pageOrientation":"landscape",但效果是整個屏幕橫屏,標題也橫,效果不同。只能通過css方法旋轉實現按鈕橫屏展示
  • 2、簽字區域有個占位符,簽字的時候需要去除,首先想到的是用個view去占位,然后點擊切換為canvas,但是個人覺的略顯刻意,就用canvas來旋轉實現,bindtouchstart時讓文字為空,這樣也多了一個設置默認文字的函數
  • 3、生成圖片,在使用wx.canvasToTempFilePath({})的時候發現生成的圖片也是反着的,這里用了一個笨方法,添加一個canvas來單獨處理圖片旋轉
//index.js
//獲取應用實例
const app = getApp()

Page({
  data: {
    context: null,
    index: 0,
    height: 0,
    width: 0,
    writeTips: '請清晰書寫您的英文簽名',
    writeTipsTrue: true,
    src:'',
    sureBtn:false,
    saveContext:null
  },
  /**記錄開始點 */
  bindtouchstart: function (e) {
    let { writeTipsTrue } = this.data
    if (writeTipsTrue) {

      this.data.context.clearRect(0, 0, this.data.width, this.data.height);
      this.setData({ writeTipsTrue: false, sureBtn:true })
    }
    this.data.context.moveTo(e.changedTouches[0].x, e.changedTouches[0].y)
  },
  /**記錄移動點,刷新繪制 */
  bindtouchmove: function (e) {
    this.data.context.setLineWidth(2)       // 設置線條寬度
    this.data.context.lineTo(e.changedTouches[0].x, e.changedTouches[0].y);
    this.data.context.stroke();
    this.data.context.draw(true);
    this.data.context.moveTo(e.changedTouches[0].x, e.changedTouches[0].y);
  },

  /**清空畫布 */
  clear () {
    let context = this.data.context
    this.setData({ writeTipsTrue: true, sureBtn:false })
    context.clearRect(0, 0, this.data.width, this.data.height);
    // this.data.saveContext.clearRect(0, 0, this.data.height, this.data.width);
    context.save();
    context.setTransform(1, 0, 0, 1, Math.ceil(this.data.width / 2), 155);        // 旋轉畫布 默認文字區域
    context.rotate(Math.PI / 2);
    let str = this.data.writeTips;
    context.setFontSize(24)
    context.setFillStyle('#ADADB2');
    context.fillText(str, 0, 0)
    context.restore();
    context.draw()
  },
  /**導出圖片 */
  export () {
    const that = this;
    let signImg;
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: that.data.width,
      height: that.data.height,
      destWidth: that.data.width,
      destHeight: that.data.height,
      canvasId: 'firstCanvas',
      success (res) {
        console.log(res.tempFilePath)
        signImg = res.tempFilePath
        that.setData({ src1: signImg})
        //下載圖片

        wx.getImageInfo({
          src: signImg, // 簽字畫布生成的暫存地址
          success (res) {
            // canvas繪制圖片需要下載圖片或者getImageInfo
            console.log(res,'res');

            let rototalImg = res.path
            that.setData({ src: rototalImg})
            if (rototalImg) {
              // 單獨處理圖片旋轉
              that.saveImg(rototalImg)

            }
          }
        })
      }
    })
  },

  // drew img
  saveImg (signImg){
    if (!this.data.sureBtn){
      app.toast(this, {
        type: 'text',
        text: '請清晰書寫您的英文簽名'
      })
      return

    }
    // 旋轉圖
    let that = this
    const context = wx.createCanvasContext('saveImg');
    this.setData({saveContext:context})
    context.translate(that.data.width / 2, that.data.height / 2)
    context.setTransform(1, 0, 0, 1, 0, Math.ceil(that.data.height / 2) -20);
    context.rotate(-Math.PI / 2)
    // context.drawImage(signImg, -that.data.width / 2, -that.data.height / 2, that.data.width, that.data.height)
    context.drawImage(signImg, 0, 0, that.data.width, that.data.height)
   
    // context.fill()
    //繪制圖片   生成圖片函數寫在draw()的回調中,不然會出現還沒有畫圖就生成圖片的問題
    context.draw(true,()=>{
      wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: that.data.height,
        height: that.data.width,
        destWidth: that.data.height,
        destHeight: that.data.width,
        canvasId: 'saveImg',
        fileType: 'png',
        success: function (res) {
          var tempFilePath = res.tempFilePath;
          console.log(tempFilePath);
          that.setData({ src: tempFilePath })
          // 生成圖片 並返回上一頁 賦值
          let curPages = getCurrentPages();
          var prevPage = curPages[curPages.length - 2]
          prevPage.setData({
            signImg: tempFilePath,
          })
          wx.navigateBack({
            delta: 1
          });
        },
        fail: function (res) {
          console.log(res);
        }
      });
    })
   
  },
  onLoad: function (options) {
    
  },
  onShow: function () {
    // 進入頁面渲染canvas
    let query = wx.createSelectorQuery();
    const that = this;
    let context
    query.select('#firstCanvas').boundingClientRect();
    query.exec(function (rect) {
      let width = rect[0].width;
      let height = rect[0].height;
      that.setData({
        width,
        height
      });
      const context = wx.createCanvasContext('firstCanvas')
      that.setData({
        context: context
      })
      context.save();
      // context.translate(Math.ceil(width / 2) - 20,0)
      context.setTransform(1, 0, 0, 1, Math.ceil(width / 2), 155);
      context.rotate(Math.PI / 2);
      let str = that.data.writeTips;
      // context.fillText(str, Math.ceil((width - context.measureText(str).width) / 2), Math.ceil(height / 2) - 20)
      context.setFontSize(24)
      context.setFillStyle('#ADADB2');
      // context.fillRect(0, 0, that.data.height, that.data.width);
      context.fillText(str, 0, 0)
      context.restore();
      context.draw()
    });
  },
  // 彈窗
  onToast(){

    app.toast(this, {
      type: 'text',
      text: '生成成功'
    })
  },
  onShareAppMessage: (res) => { }
})

相關注釋代碼中都有,也么有優化,有好的方法,還希望大佬們多多指點


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM