uniapp 微信小程序手动签名

147 阅读2分钟
<view v-if='signImage' class="sign-img">
    <image :src='signImage' class="img-block"></image>
</view>
<canvas class='firstCanvas' 
        type="2d"
        id="firstCanvas"
        @touchstart='start'
        @touchmove='move'
        @touchend='end'
        :disable-scroll='true' v-show="!signImage">
</canvas>

<view class="item flex flex-c chongqian" @tap='clearClick'>
        {{signImage ? '重签' : '重置'}}
</view>
<view class="item flex flex-c complate" @click="overSign">
        提交
</view>

js

//定义全局常量
let canvas_instance = null; //canvas实例
let content = null;         //上下文内容
let touchs = [];
let default_canvas = {
        w:356,
        h:160
};                                    // 设计图上的宽,高(仅动态时按比例计算)
let canvasw = 0,canvash = 0;          // 设计图上的宽,高(仅动态时按比例计算)
let _that;

//获取系统信息配置动态canvas宽高
uni.getSystemInfo({
        success: function(res) {
                canvasw = parseInt(res.windowWidth*0.95);
                canvash = parseInt((default_canvas.h/default_canvas.w)*canvasw)
        },
})
onReady(options) {
    wx.createSelectorQuery().in(this)
        .select('#firstCanvas') // 在 WXML 中填入的 id
        .node(({ node: canvas }) => {
                    canvas_instance = canvas
                    console.log(canvasw,canvash)
                    canvas.width = canvasw
                    canvas.height = canvash
            content = canvas.getContext('2d')

                    //设置线的颜色
                    content.strokeStyle = "#000"
                    //设置线的宽度
                    content.lineWidth = 5
                    //设置线两端端点样式更加圆润
                    content.lineCap = 'round'
                    //设置两条线连接处更加圆润
                    content.lineJoin = 'round'
        })
        .exec()
},
methods: {
        overSign: function() {
                let that = this
                if (this.signImage != "") {
                        uni.showToast({
                                title: '已签名,无需提交',
                                icon: "none",
                                duration: 1500,
                                mask: true
                        })
                        return false
                }
                if (this.isEnd) {
                        console.log(canvas_instance)

                        content.clearRect(0, 0, canvasw, canvash)
                        content.stroke();
                        uni.canvasToTempFilePath({
                                canvas: canvas_instance,
                                x: 0,
                                y: 0,
                                success: function(res) {
                                        //打印图片路径
                                        console.log(res)
                                        console.log('完成签名')
                                        //设置图片
                                        that.signImage = res.tempFilePath;


                                },
                                fail(err) {
                                        console.log(err)
                                }
                        },this)
                } else {
                        this.$popup.show({
                                icon: "fail",
                                title:'请先完成签名'
                        })
                }

        },

        // 画布的触摸移动开始手势响应
        start(event) {
                console.log(event)
                console.log("触摸开始" + event.changedTouches[0].x)
                console.log("触摸开始" + event.changedTouches[0].y)
                //获取触摸开始的 x,y
                let point = {
                        x: event.changedTouches[0].x,
                        y: event.changedTouches[0].y
                }
                // console.log(point)
                touchs.push(point);

        },
        // 画布的触摸移动手势响应
        move(e) {
                let point = {
                        x: e.touches[0].x,
                        y: e.touches[0].y
                }
                // console.log(point)
                touchs.push(point)
                if (touchs.length >= 2) {
                        this.draw(touchs)
                }
        },

        // 画布的触摸移动结束手势响应
        end(e) {
                // 设置为已经签名
                this.isEnd = true;
                console.log('end')
                // 清空轨迹数组
                touchs.pop()

        },

        //绘制
        draw: function(touchs) {
                let point1 = touchs[0]
                let point2 = touchs[1]
                touchs.shift()
                content.moveTo(point1.x, point1.y)
                content.lineTo(point2.x, point2.y)
                content.closePath(); //虽然我们只绘制了两条线段,但是closePath会closePath,仍然是一个3角形
                content.stroke();
        },
        //清除操作
        clearClick: function() {
                if (this.signImage != "") {
                        this.signImage = ''
                        this.isEnd = false
                }else{
                        this.isEnd = false
                        // uni.showToast({
                        // 	title: '已提交,无法重置',
                        // 	icon: "none",
                        // 	duration: 1500,
                        // 	mask: true
                        // })
                        // return false
                }
                // 设置为未签名
                //清除画布,
                content.beginPath()
                content.clearRect(0, 0, canvasw, canvash)
                // content.save();


                // 1此方案无效
                // content.save();
                // content.fillStyle = '#ffffff';
                // content.setTransform(1, 0, 0, 1, 0, 0);
                // content.clearRect(0, 0, canvasw, canvash)
                // content.restore();
        },
},

CSS

<style lang="scss" scoped>
	.pop-content{
		background-color: $page-bg-gray;
		border-top-left-radius: $border-radius;
		border-top-right-radius: $border-radius;
		padding-bottom: 20rpx;
	}
	
	
	.sign-title {
		font-weight: 750;
		padding: 20upx;
	}
	.box-content{
		width: 750rpx;
		padding: 0 20rpx;
		height: auto;
		.sign-box{
			width: 100%;
			height: 320rpx;
			border-radius: 10upx;
			overflow: hidden;
			.sign-img {
				width: 100%;
				height: 100%;
			}
			.firstCanvas {
				width: 100%;
				height: 100%;
				background-color: white;
			}
		}
		
		.tips {
			color: #999999;
			font-size: 26rpx;
			padding: 20rpx 0;
		}
	}
	.controls{
		width: 100%;
		height: 130rpx;
		font-size: 28rpx;
		background-color: #fff;
		padding-top: 10rpx;
		.item{
			width: 40%;
			height: 80rpx;
			margin-left: 5%;
			border-radius: 40rpx;
			&.chongqian {
				background-color: #F8F8F8;
				color: #999999;
			}
			&.complate{
				background-color: #5F853D;
				color: #FFFFFF;
			}
			&:active {
				background-color: #CCCCCC;
				color: #333333;
			}
		}
	}



</style>

此处仅为代码,自行封装外部,因原为canvas_id 形式,线改版为type:2d,canvasToTempFilePath后必须继承this