微信小程序vant+canvas实现签名

微信小程序canvas实现签名

话不多说,先看效果
图1.签名样式
在这里插入图片描述
图2.页面展示效果
在这里插入图片描述

下面是具体代码

canvas.wxml


<view class="signBox border">
  <view class="flex-center">
    <view>商户签字</view>
    <van-image style="padding-left:30rpx" wx:if="{{sign}}" src="{{sign}}" width="100" height="50" fit="contain"/>
  </view>
  <van-button type="primary" size="small" color="#12b2a8" bind:click="toSign">{{form.sign == '' ? '点击签名' : '点击重签'}}
  </van-button>
  <!-- <button style="margin-top: 30rpx;" bindtap="submitSignature" disabled="{{!isSignatureFinish}}">提交保存</button> -->
</view>
<view class="bottom">
  <van-button block round type="primary" color="#12b2a8" bind:click="makeEOrder">
    完成</van-button>
</view>
<page-container show="{{showPage}}" overlay="{{false}}" round="{{false}}" close-on-slideDown="{{false}}" z-index="1000">
  <view class="flex" style="height: 100vh;">
    <view class="sign-btn-container">
      <view class="cu-btn" bindtap="hideSignPage">取消/返回</view>
      <view class="cu-btn {{isSignatureFinish?'bg-blue light':''}}" bindtap="clearCanvas">重新签名</view>
      <view class="cu-btn {{isSignatureFinish?'bg-blue light':''}}" bindtap="confirmSign">完成签名</view>
    </view>
    <canvas id="canvas" style="position:{{showPage?'relative':'fixed'}};left:{{showPage?'':'100%'}};" canvas-id="canvas" class="canvas" :disable-scroll="true" bindtouchstart="handleTouchStart" bindtouchmove="handleTouchMove" bindtouchend="handleTouchEnd" bindtouchcancel="handleTouchCancel" disable-scroll="true" />
  </view>
</page-container>
<canvas id="canvas-temp" style="width: {{canvasTempWidth}}px; height: {{canvasTempHeight}}px;" canvas-id="canvas-temp" class="canvas-temp"></canvas>
<van-dialog id="van-dialog" />
<van-notify id="van-notify" />

canvas.js

var util = require('../../utils/util.js');
import Notify from '@vant/weapp/notify/notify';
Page({

  /**
   * 页面的初始数据
   */
  data: {
    showPage:false,
    isSignatureFinish: false,
    moveLength: 0, //移动一定距离后才能提交保存
    canvasTempWidth: wx.getSystemInfoSync().screenWidth,
    canvasTempHeight: wx.getSystemInfoSync().screenWidth * 0.5,
  },
  //跳转签名页面
  toSign() {
    this.setData({
      showPage: true
    });
  },

 
  //生成电子巡检单
  makeEOrder() {
     if (this.data.sign == '') {
      wx.showToast({
        title: '请先完成商户签字',
        icon: 'none'
      })
    } else {
      
    }
  },
  // 签名部分
  hideSignPage() {
    this.setData({
      showPage: false
    });
  },
  confirmSign() {
    let _this = this
    _this.generateSignImage('canvas').then(res => {
      console.log('图片地址:', res)
 
      wx.getImageInfo({
        src: res,
        success(info) {
          let width = info.width
          let height = info.height
          //先重置canvas-temp
          _this.ctx2.draw(false, ()=>{
          let dx = _this.data.canvasTempWidth
          let dy = _this.data.canvasTempHeight
          //把原点移动到中心点位置
          _this.ctx2.translate(dx / 2, dy / 2)
          _this.ctx2.rotate(270 * Math.PI / 180)
          
          let dWidth = dx / height * width
          let dHeight = dx
          //drawImage参数说明
          //imageResource
          //imageResource的左上角在目标 canvas 上 x 轴的位置
          //imageResource的左上角在目标 canvas 上 y 轴的位置
          //在目标画布上绘制 imageResource 的宽度,允许对绘制的 imageResource 进行缩放
          //在目标画布上绘制 imageResource 的高度,允许对绘制的 imageResource 进行缩放
          
          _this.ctx2.drawImage(res, -dWidth / 2,-dHeight / 2, dWidth, dHeight)
          //canvas-temp图片绘制完成后
          _this.ctx2.draw(false, ()=>{
              _this.generateSignImage('canvas-temp').then(res => {
                console.log('图片地址:', res)
                _this.setData({
                  sign:res
                })
                _this.hideSignPage()
              })
          })
        })
        }
      })
    })
  },
  // submitSignature(){
  //   console.log(this.data.sign)
  //   wx.showToast({
  //     icon:'none',
  //     title: '获取sign变量图片地址提交到自己的服务器',
  //   })
  // },

  initCanvas() {
    /* 设置线条颜色 */
    this.canvasContext.setStrokeStyle('#0081ff'); //2A2A2A
    /* 设置线条粗细 */
    this.canvasContext.setLineWidth(4);
    /* 设置线条的结束端点样式 */
    this.canvasContext.setLineCap('round');
  },

  /* 触摸开始 */
  handleTouchStart(e) {
    console.log(e)
    this.drawStartX = e.changedTouches[0].x;
    this.drawStartY = e.changedTouches[0].y;
    console.log('触摸开始', this.drawStartX, this.drawStartY)
    this.canvasContext.beginPath();
  },
  /* 触摸移动 */
  handleTouchMove(e) {
    /* 记录当前位置 */
    const tempX = e.changedTouches[0].x;
    const tempY = e.changedTouches[0].y;
    // console.log('触摸移动', tempX, tempY)
    this.data.moveLength += Math.abs(this.drawStartX - tempX) + Math.abs(this.drawStartY - tempY)
    /* 画线 */
    this.canvasContext.moveTo(this.drawStartX, this.drawStartY);
    this.canvasContext.lineTo(tempX, tempY);
    this.canvasContext.stroke();

    /* 旧版draw方法,新版本不需要draw */
    this.canvasContext.draw(true);

    /* 重新记录起始位置 */
    this.drawStartX = tempX;
    this.drawStartY = tempY;
  },
  /* 触摸结束 */
  handleTouchEnd(e) {
    console.log('触摸结束')
    this.canvasContext.save();
    this.setData({
      isSignatureFinish: this.data.moveLength > 100
    })
  },
  /* 触摸取消 */
  handleTouchCancel(e) {
    console.log('触摸取消')
    this.canvasContext.save();
  },
  /* 清空画布 */
  clearCanvas() {
    console.log('清空画布')
    this.canvasContext.draw()
    this.initCanvas()
    this.data.moveLength = 0
    this.setData({
      isSignatureFinish: false
    })
  },
  /* 生成签名图片 */
  generateSignImage(canvasId) {
    console.log('Canvas生成图片')
    return new Promise((resolve, reject) => {
      wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        canvasId: canvasId, // 旧版使用id
        fileType: 'png',
        quality: 1,
        success: res => {
          resolve(res.tempFilePath)
        },
        fail: err => {
          reject(err);
        }
      })
    })
  },
  
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {
    //第一个canvas
    this.canvasContext = wx.createCanvasContext('canvas');
    this.initCanvas()
    //第二个canvas
    this.ctx2 = wx.createCanvasContext('canvas-temp');
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    // if (this.data.sign) {
    //   //商户签字上传服务器
    //   this.upLoadImg(this.data.sign, 'form.sign');
    // }
  }
})

canvas.wxss

.signBox {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10rpx 30rpx;
}
.bottom {
  margin: 100rpx 20rpx;
  padding-bottom: 20px;
}
.title {
  padding: 20rpx 30rpx 0;
}
.border {
  margin-top: 20rpx;
  border-top: 1px solid #b3b3b3;
}
.flex-center {
  display: flex;
  align-items: center;
}
.canvas {
  width: 90vw;
  height: 100vh;
}
.canvas-temp {
  position:fixed;left:100%;
}
/* 签名部分 */
.sign-btn-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 10vw;
  justify-content: space-around;
}

.sign-btn-container view {
  transform: rotate(90deg);
  width: 100px;
  margin-left: -8vw;
}
.cu-btn {
  position: relative;
  border: 0rpx;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding: 0 30rpx;
  font-size: 28rpx;
  height: 64rpx;
  line-height: 1;
  text-align: center;
  text-decoration: none;
  overflow: visible;
  margin-left: initial;
  transform: translate(0rpx, 0rpx);
  margin-right: initial;
}
.bg-blue{
  background-color: #0081ff;
  color: #ffffff;
}
.light{
  color:#0081ff;
  background-color:#cce6ff;
}

canvas.json

{
  "usingComponents": {
    "van-radio": "@vant/weapp/radio/index",
    "van-radio-group": "@vant/weapp/radio-group/index",
    "van-uploader": "@vant/weapp/uploader/index",
    "van-image": "@vant/weapp/image/index"
  },
  "navigationBarTitleText": "签名"
}
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微信小程序vant weapp提供了TreeSelect组件来实现三级分类选择。要实现三级分类选择,我们需要先获取分类数据,并将其转换为树状结构。 首先,在小程序页面的json文件中引入vant组件库,并设置所需的TreeSelect组件。 ```json { "usingComponents": { "van-tree-select": "/path/to/vant/weapp/dist/tree-select/index" } } ``` 然后,在小程序页面的wxml文件中添加TreeSelect组件,并绑定所需的属性和事件。 ```html <van-tree-select items="{{ treeData }}" main-active-index="{{ mainActiveIndex }}" activeId="{{ activeId }}" bind:click-nav="handleClickNav" bind:click-item="handleClickItem" /> ``` 在小程序页面的js文件中,定义相关数据和方法。 ```javascript Page({ data: { treeData: [], // 分类数据 mainActiveIndex: 0, // 主选项卡索引 activeId: '', // 选中的分类id }, onLoad() { // 获取分类数据,并将其转换为树状结构 const data = this.getCategoryData(); const treeData = this.convertToTree(data); this.setData({ treeData: treeData }); }, getCategoryData() { // 从接口或本地获取分类数据 // 返回分类数据数组 }, convertToTree(data) { // 将分类数据转换为树状结构 // 返回树状结构的数据 }, handleClickNav(event) { // 切换主选项卡时的回调函数 this.setData({ mainActiveIndex: event.detail.index }); }, handleClickItem(event) { // 选择子分类时的回调函数 this.setData({ activeId: event.detail.id }); } }); ``` 通过以上步骤,我们就可以使用微信小程序vant weapp实现三级treeselect分类选择功能了。需要注意的是,具体的分类数据获取和转换还需要根据实际情况进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值