小程序利用canvas实现手写签名,供大家参考,具体内容如下

设置小程序横屏

在page.json或对应页面 .json文件中设置
landscape代表固定横屏

"pageOrientation":"landscape"

手写签名

创建canvas画布 设置监听触摸开始 移动 结束等时间

此处为uniapp示例 原生小程序的也可参考进行修改(只需将@touchmove等事件换为bindtouchmove等微信事件即可)

<view class='contents'>
        <canvas class='firstCanvas' canvas-id="firstCanvas" @touchmove='move' @touchstart='start($event)'
            @touchend='end' @touchcancel='cancel' @longtap='tap' disable-scroll='true' @error='error'>
        </canvas>
        <view class="btnBox">
            <view class="btn1" @tap='clearClick'>重签</view>
            <view class="btn2" @tap="overSign">完成签名</view>
     </view>
</view>
page {
        background-color: #f2f2f2;
    }

    canvas {
        background-color: #fff;
        width: calc(100% - 20px);
        height: calc(100% - 70px);
        margin: 10px;
        position: absolute;
    }

    .btnBox {
        display: flex;
        height: 50px;
        width: 100%;
        position: fixed;
        left: 0;
        bottom: 0;
    }

    .btnBox view {
        width: 50%;
        text-align: center;
        height: 50px;
        line-height: 50px;
        color: #FFFFFF;
    }

    .btnBox view:active {
        background-color: #CCCCCC;
        color: #333333;
    }

    .btn1{
        background-color: #FF8F58;
    }

    .btn2{
        background-color: #0599D7;
    }

重点js

var content = null;
var touchs = [];
var canvasw = 0;
var canvash = 0;
var _that;
export default {
    data() {
        return {
            isEnd: false, // 是否签名
            srcA: ''
        }
    },

    methods: {
        overSign: function() {
            if (this.isEnd) {
                let that = this
                uni.canvasToTempFilePath({
                    canvasId: 'firstCanvas',
                    fileType: 'png',
                    success: function(res) {
                        //打印图片路径
                        console.log(res.tempFilePath)
                        console.log('完成签名')
                        // 可以再次进行直接保存图片到本地,这个保存就不写了可参考之前的canvas图片保存到本地
                        // 一般签名都是要返回前一页进行提交,所以在此将图片写到微信内部文件(不会出现在手机相册中)返回上一页获取,在上一页提交后在将图片删除
                        let fsm = uni.getFileSystemManager();
                        fsm.readFile({
                            filePath: res.tempFilePath,
                            success: function(res) {
                                //转换成功
                                var arrayBuffer = res.data
                                fsm.writeFile({
                                    filePath: `${wx.env.USER_DATA_PATH}/autograph.png`,
                                    data: arrayBuffer,
                                    encoding: 'binary',
                                    success() {
                                        console.log('写入成功')
                                        uni.navigateBack()
                                    },
                                    fail(err) {
                                        console.log(err)
                                    },
                                });
                            },
                            fail: function(e) {}
                        })
                    }
                })
            } else {
                uni.showToast({
                    title: '请先完成签名',
                    icon: "none",
                    duration: 1500,
                    mask: true
                })
            }

        },
        // 画布的触摸移动开始手势响应
        start: function(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: function(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: function(e) {
            // console.log("触摸结束" + e)
            // 设置为已经签名
            this.isEnd = true
            // 清空轨迹数组
            for (let i = 0; i < touchs.length; i++) {
                touchs.pop()
            }

        },
        // 画布的触摸取消响应
        cancel: function(e) {
            console.log("触摸取消" + e)
        },
        // 画布的长按手势响应
        tap: function(e) {
            console.log("长按手势" + e)
        },
        error: function(e) {
            console.log("画布触摸错误" + e)
        },
        //绘制
        draw: function(touchs) {
            // console.log(touchs[0], touchs[1])
            let point1 = touchs[0]
            let point2 = touchs[1]
            touchs.shift()
            content.moveTo(point1.x, point1.y)
            content.lineTo(point2.x, point2.y)
            content.stroke()
            content.draw(true)
        },
        //清除操作
        clearClick: function() {
            // 设置为未签名
            this.isEnd = false
            //清除画布
            content.clearRect(0, 0, canvasw, canvash)
            content.draw(true)
        },
    },
    /*生命周期函数--监听页面加载 */
    onLoad: function(options) {
        _that = this
        let dev = uni.getSystemInfoSync()
        console.log(dev)
        // 获取横屏的宽高 设置画布的大小
        // screenWidth windowHeight
        canvasw = dev.screenWidth - 20
        canvash = dev.screenHeight - 70
        //获得Canvas的上下文
        content = wx.createCanvasContext('firstCanvas')
        //设置线的颜色
        content.setStrokeStyle("#000")
        //设置线的宽度
        content.setLineWidth(5)
        //设置线两端端点样式更加圆润
        content.setLineCap('round')
        //设置两条线连接处更加圆润
        content.setLineJoin('round')
        content.setFillStyle('white'); //填充白色

        content.fillRect(0, 0, canvasw, canvash); //画出矩形白色背景

        content.restore()
        content.save()
    },
}

上一页可在onshow中获取签名的图片 (若签名没有writeFile则可不理会下方的)

// 获取本地保存的图片
getImg() {
        var timestamp = new Date().getTime();
        uni.getImageInfo({
            src: `${wx.env.USER_DATA_PATH}/autograph.png`,
            success: function(res) {
                console.log(res.path)
                _that.srcA = res.path
                hasQM = true
            },
            fail: function(err) {
                console.log(err)
                _that.srcA = ''
            },
        })
    },
    //删除缓存的图片
    delPic() {
            let fsm = uni.getFileSystemManager();
            fsm.unlink({
                filePath: `${wx.env.USER_DATA_PATH}/autograph.png`,
                success(res) {
                    console.log(res)
                    _that.srcA = ''
                    hasQM = false
                },
                fail(res) {
                    console.error(res)
                }
    })
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持阿兔在线工具。

点赞(0)

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部