APP、h5使用canvas实现一个手写签名

代码如下:

<template>
    <view>
        <view style="width: 20%;">
            <view @click='createCanvas'>
                手写签名:
                <u-image v-if="form.autographUrl" :src="form.autographUrl"
                    style="width: 200rpx;height: 80rpx;border: 1px solid black;"></u-image>
                <view v-else style="border: 1px solid black;width: 200rpx;height: 80rpx;"></view>
            </view>
        </view>
        <u-modal v-model="showAutograph" border-radius="14" width="605rpx" :show-title="false"
            :confirm-style="{ 'font-size': '29rpx', 'color': '#341DB7' }" :show-cancel-button='true'
            :cancel-style="{ 'font-size': '29rpx', 'color': '#666666' }" @confirm="confirm" @cancel="cancel">
            <view class="x-modal">
                <view class="x-m-title">
                    <text>请在框内进行签名</text>
                    <view class="xm-t-clear" @click="clear">
                        <text>清除</text>
                    </view>
                </view>
                <view class="x-m-con">
                    <canvas class="mycanvas" canvas-id="mycanvas" @touchstart="touchstart" @touchmove="touchmove"
                        @touchend="touchend"></canvas>
                </view>
            </view>
        </u-modal>
    </view>
</template>
<script>
export default {
    data() {
        return {
            showAutograph: false, //签名弹框是否显示
            ctx: '', //绘图图像
            points: [], //路径点集合 
            form: {
                autographUrl: null,//签名
            },
        }
    },
    mounted() {

    },
    methods: {
        createCanvas() {
            this.showAutograph = true;
            //创建绘图对象
            this.ctx = uni.createCanvasContext("mycanvas", this);
            //设置线条的粗细,单位像素,省略
            this.ctx.lineWidth = 4;
            this.ctx.lineCap = "round"
            this.ctx.lineJoin = "round"

        },
        //清空画布
        clear() {
            let that = this;
            uni.getSystemInfo({
                success: function (res) {
                    let canvasw = res.windowWidth;
                    let canvash = res.windowHeight;
                    that.ctx.clearRect(0, 0, canvasw, canvash);
                    that.ctx.draw(true);
                },
            })
        },
        draw() {
            let point1 = this.points[0]
            let point2 = this.points[1]
            this.points.shift()
            // (你想要让你手中画笔搁哪个位置上)
            this.ctx.moveTo(point1.X, point1.Y)
            // 绘制线条的跨越状态,从x轴开始,y轴结束,创建到达位置 (x,y)的一条线	
            this.ctx.lineTo(point2.X, point2.Y)
            //开始绘制图像	
            this.ctx.stroke()
            this.ctx.draw(true)
        },
        //关闭并清空画布
        cancel() {
            this.showAutograph = false;
            this.clear();
        },
        touchend() {
            this.points = [];
        },
        //触摸开始,获取到起点
        touchstart(e) {
            let startX = e.changedTouches[0].x;
            let startY = e.changedTouches[0].y;
            let startPoint = {
                X: startX,
                Y: startY
            };
            this.points.push(startPoint);
            //每次触摸开始,开启新的路径
            this.ctx.beginPath();
        },
        //触摸移动,获取到路径点
        touchmove(e) {
            let moveX = e.changedTouches[0].x;
            let moveY = e.changedTouches[0].y;
            let movePoint = {
                X: moveX,
                Y: moveY
            };
            this.points.push(movePoint); //存点
            let len = this.points.length;
            if (len >= 2) {
                this.draw(); //绘制路径
            }
        },
        //保存签名
        confirm() {
            let that = this;
            uni.canvasToTempFilePath({
                canvasId: 'mycanvas',
                fileType: 'png',
                quality: 1, //图片质量
                success: function (res) {
                    //这里的res.tempFilePath就是生成的签字图片
                    // console.log(res.tempFilePath);
                    //上传
                    uni.uploadFile({
                        url: that.vuex_config.baseUrl + '/fileUpload', // 仅为示例,非真实的接口地址
                        header: { Authorization: that.vuex_token },
                        formData: { type: "commont" },
                        filePath: res.tempFilePath,
                        name: 'files',
                        success(res) {
                            console.log(127, res);
                            if (res.statusCode == 200) {
                                const data = JSON.parse(res.data)
                                that.form.autographUrl = data.data[0].fileUrl
                            }

                        }
                    })
                }
            });

        },
    }

}
</script>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,可以先在template中添加一个canvas标签,然后钩子函数中获取该标签并设置画布大小和绘制笔刷等属性。接着可以监听鼠标或触摸事件,在相应的事件处理函数中获取鼠标或触摸点坐标,并在画布上绘制路径。最后可以添加清空按钮,通过清空画布达到重新签名的效果。具体代码实现可以参考以下示例: ```html <template> <div> <canvas ref="canvas" @mousedown="startDrawing" @touchstart="startDrawing" @mousemove="drawing" @touchmove="drawing" @mouseup="stopDrawing" @touchend="stopDrawing" :width="width" :height="height" style="border: 1px solid #ccc;"></canvas> <button @click="clear">清空</button> </div> </template> <script> export default { data() { return { ctx: null, isDrawing: false, lineWidth: 2, strokeStyle: '#333', width: 300, height: 150 } }, mounted() { const canvas = this.$refs.canvas this.ctx = canvas.getContext('2d') this.ctx.lineJoin = 'round' this.ctx.lineCap = 'round' this.ctx.lineWidth = this.lineWidth this.ctx.strokeStyle = this.strokeStyle }, methods: { startDrawing(event) { event.preventDefault() this.isDrawing = true this.ctx.beginPath() const pos = this.getMousePosition(event) this.ctx.moveTo(pos.x, pos.y) }, drawing(event) { event.preventDefault() if (this.isDrawing) { const pos = this.getMousePosition(event) this.ctx.lineTo(pos.x, pos.y) this.ctx.stroke() } }, stopDrawing(event) { event.preventDefault() this.isDrawing = false }, clear() { this.ctx.clearRect(0, 0, this.width, this.height) }, getMousePosition(event) { const canvas = event.target const rect = canvas.getBoundingClientRect() const scaleX = canvas.width / rect.width const scaleY = canvas.height / rect.height return { x: (event.clientX - rect.left) * scaleX, y: (event.clientY - rect.top) * scaleY } } } } </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值