• 微信小程序电子签名实现


    实现签名方法就是使用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,
         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,
           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,
             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) => { }
    })
    

    相关注释代码中都有,也么有优化,有好的方法,还希望大佬们多多指点

  • 相关阅读:
    JDBC-HikariCP
    11、JDBC-Druid
    JDBC-DBCP
    JDBC-C3P0
    第十七篇-使用RadioGroup实现单项选择
    第十六篇-使用CheckBox实现多项选择
    第一篇-ubuntu18.04访问共享文件夹
    第十五篇-EditText做简单的登录框
    第十四篇-ImageButton控制聚焦,单击,常态三种状态的显示背景
    第十三篇-通过Button设置文本背景颜色
  • 原文地址:https://www.cnblogs.com/wsjaizlp/p/14944258.html
Copyright © 2020-2023  润新知