微信小程序canvas签名组件

效果图

1、点击横线

在这里插入图片描述

2、展示弹窗

在这里插入图片描述

3、完成签名

在这里插入图片描述

signature组件代码

JS

// pages/component/signature/signature.js
var cxt = null; // 使用 wx.createContext 获取绘图上下文 cxt
var arrx = []; //所有点的X轴集合
var arry = []; //所有点的Y轴集合
var canvasw = 0; //画布的宽 
var canvash = 0; //画布的高
// var canvasTop=0;
// var canvasLeft=0;
Component({
    /**
     * 组件的属性列表
     */
    properties: {},

    /**
     * 组件的初始数据
     */
    data: {
        signatureImg: ""
    },

    /**
     * 组件的方法列表
     */
    methods: {
        //创建canvas上下文
        createdCanvas() {
            wx.showLoading({
                title: '加载中...',
                mask: true
            })
            // 使用 wx.createContext 获取绘图上下文 cxt
            //创建 canvas 的绘图上下文,因为这里是封装成组件,所有需要加this
            cxt = wx.createCanvasContext('canvas', this);
            cxt.beginPath();
            //封装成组件,所有需要in(this),如果不加无法创建画布
            var query = wx.createSelectorQuery().in(this).select('.handCenter');
            query.boundingClientRect(rect => {
                // canvasTop = rect.top;
                // canvasLeft = rect.left;
                canvasw = rect.width / 2;
                canvash = rect.height / 2;
                // var ratio = 2;
                // while (canvasw > 150){// 保证宽在150以内
                //   canvasw = Math.trunc(res.width / ratio)
                //   canvash = Math.trunc(res.height / ratio)
                //     ratio++;
                // }
                wx.hideLoading()
            }).exec();
        },
        //canvas发生错误时触发
        canvasIdErrorCallback(e) {
            console.error(e.detail.errMsg)
        },
        //canvas触摸开始
        canvasStart(e) {
            arrx.push(e.changedTouches[0].x);
            arry.push(e.changedTouches[0].y);
        },
        //canvas触摸过程中
        canvasMove(e) {
            let len = arrx.length;
            cxt.moveTo(arrx[len - 1], arry[len - 1]); //把路径移动到画布中指定的点,第一个参数为x轴,第二个参数为y轴
            arrx.push(e.changedTouches[0].x); //手指移动过程中canvas的横坐标存入到全局数组变量arrx中
            arry.push(e.changedTouches[0].y); //手指移动过程中canvas的纵坐标存入到全局数组变量arry中
            cxt.lineTo(e.changedTouches[0].x, e.changedTouches[0].y); //moveTo坐标到lineTo坐标的
            cxt.setLineWidth(4); //设置线条的宽度
            cxt.setLineCap('round'); //设置结束时 点的样式
            cxt.stroke(); //画线
            cxt.draw(true); //设置为true时,会保留上一次画出的图像,false则会清空(方式二设置为false,一为true)
        },
        getImg() {
            if (arrx.length == 0) {
                wx.showModal({
                    title: '提示',
                    content: '签名内容不能为空!',
                    showCancel: false
                });
                return false;
            };
            wx.showLoading({
                title: '签名生成中..',
                mask: true
            })
            let that = this;
            wx.canvasToTempFilePath({
                canvasId: 'canvas',
                success: function (res) {
                    that.setData({
                        signatureImg: res.tempFilePath
                    })
                    wx.hideLoading();
                    console.log();
                    //子组件传递给父组件一个方法canvasDis,并传递一个参数src给父组件
                    that.triggerEvent("canvasDis", {
                        signatureImg: res.tempFilePath
                    })
                }
            }, this)
        },
        cleardraw() {
            //清除画布
            arrx = [];
            arry = [];
            cxt.clearRect(0, 0, canvasw, canvash);
            cxt.draw();
            this.setData({
                signatureImg: ''
            });
        },
        canvasEnd(e) {}
    },
    ready() {
        this.createdCanvas()
    }
})

WXML

<!-- 签名组件 -->
<view class="wrapper">
<view class="title">
    请在下方灰色框内签名:
</view>
    <view class="handCenter">
        <canvas class="canvas" id="canvas" canvas-id="canvas" disable-scroll="true" bindtouchstart="canvasStart" bindtouchmove="canvasMove" binderror="canvasIdErrorCallback">
        </canvas>
    </view>
    <view class="handBtn">
        <button catchtap="cleardraw" class="delBtn">清空</button>
        <button catchtap="getImg" class="subBtn">完成</button>
    </view>
</view>

CSS

.wrapper{
    position: fixed;
    top:20rpx;
    bottom: 0;
    right: 0;
    left: 0;
    box-sizing: border-box;
    background-color: #fff;
    z-index: 99999;
    overflow-y: auto;
  }
  .title{
    margin: 20rpx;
    border-radius:16rpx;
  }
  .handCenter{
    box-sizing: border-box;
    width: 100%;
    background-color: rgba(228, 228, 228, 0.39);
  }
  canvas {
    width:100%;
    height: 1000rpx;
    margin:auto;
  }
  .overImg{
    width: 200rpx;
    height: 200rpx;
  }
  .handCenter {
    box-sizing: border-box;
  }
  .handBtn {
    height: 100rpx;
    display: flex;
    align-content: space-between;
    align-items: center;
    margin:40rpx 0;
    padding: 0 20rpx;
  }
  .delBtn {
    width: 40%;
    color: #666;
  }
  .subBtn {
    width: 40%;
    background: #008ef6;
    color: #fff;
  }
  button{
    font-size: 34rpx;
  }

父组件引用代码

WXML

<view>(签名)</view>
<view wx:if="{{!signatureImg}}" class="signature_line" bindtap="signature" data-index="{{index}}"></view>
<image class="signature_img" wx:if="{{signatureImg}}" src="{{signatureImg}}"  bindtap="signature"></image>
<page-container show="{{isOpen}}" position="{{containerType}}" bind:afterleave="closeContainer">
    <view wx:if="{{containerType==='center'}}">
        <signature bindcanvasDis="handlChangeCanvasShow"></signature>
    </view>
</page-container>

JS

	data:{
	        containerType: 'bottom',
	         isOpen: false,
	         signatureImg: ''
	}
  // 签名面板
    signature: function (e) {
        if(this.data.isConfirm){
            return
        }
        let {
            index
        } = e.currentTarget.dataset
        this.setData({
            containerType: 'center',
            isOpen: true
        })
    },
        // 关闭半窗口
    closeContainer: function () {
        this.setData({
            isOpen: false,
            containerType: ''
        })
    },
     //handlChangeCanvasShow自定义事件,子组件传递过来的方法和数据
    handlChangeCanvasShow(e) {
        let that = this
        if (e.detail.signatureImg != '') {
            that.setData({
                signatureImg: e.detail.signatureImg
            })
            that.closeContainer()
        }
    },

JSON

    "usingComponents": {
        "signature":"../../components/signature/signature"
    },
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值