最近开发的一个项目需要用到签字功能,本来vue2.0可以直接使用vue-esign插件,实现签字。多么的方便,奈何项目使用vue3.0开发vue-esign不好使,那就只能自己动手封装一个签字组件了。

签字功能实际上就是获取鼠标运动轨迹并将轨迹绘画出来而已

<template>
    <div class="container">
        <canvas v-show="showCanvas" @click="testFun" id="drawingBorad" width="500" height="500"
                style="background-color: #fff;"></canvas>
        <img v-show="!showCanvas" :src="ImgSrc" style="background-color: #fff;"/>

    </div>
</template>
<script>
import {onMounted, reactive, toRefs, defineComponent, getCurrentInstance} from "vue";

export default defineComponent({
    props: ['ImgSrc', 'show'],
    setup(props, ctx) {
        const {proxy} = getCurrentInstance(); // 获取挂载的原型
        const router = proxy.useRouter(); // 获取路由
        const route = proxy.useRoute(); // 获取路由
        const store = proxy.useStore(); // 设置vuex数据
        const getInitalState = () => {
            return {
                showCanvas: true,
                canvas: null,
                context: null,
                //线宽
                lwidth: 9,
                //画笔颜色
                lcolor: "orange",
                ImgSrc: '',
                width: "",
                height: "",
                fillStyle: {
                    type: String,
                    default: ""
                }
            }
        }
        const state = reactive(getInitalState());


        onMounted(() => {if (props.show) {
                init()
                console.log('画画板')
            } else {
                state.showCanvas = props.show;
                state.ImgSrc = props.ImgSrc
                console.log('显示照片')
            }
        });


        function init() {

            drawCanvas();
        }

        function testFun() {
            console.log('点击了画板');
        }

        function drawCanvas() {
            console.log(document)
            state.canvas = document.getElementById("drawingBorad");
            console.log('显示获取dom', state.canvas);
            state.context = state.canvas.getContext("2d");
            state.context.lineWidth = 6.0;//设置线段厚度的属性(即线段的宽度)

            // 触摸点按下事件
            state.canvas.addEventListener('touchstart', function (event) {
                if (event.targetTouches.length == 1) {
                    var touch = event.targetTouches[0];
                    state.context.beginPath();
                    // moveTo(x, y) 将一个新的子路径的起始点移动到(x,y)坐标的方法
                    state.context.moveTo(touch.clientX - state.canvas.offsetLeft, touch.clientY - state.canvas.offsetTop);

                    // 拖动触摸点事件
                    state.canvas.addEventListener('touchmove', function (event) {
                        var touche = event.targetTouches[0];
                        //使用直线连接子路径的终点到x,y坐标的方法(并不会真正地绘制)
                        state.context.lineTo(touche.clientX - state.canvas.offsetLeft, touche.clientY - state.canvas.offsetTop);
                        // stroke 它会实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径,默认颜色是黑色
                        state.context.stroke();
                    }, false)

                    // 离开屏幕的事件
                    state.canvas.addEventListener('touchend', function (event) {
                        // closePath 它尝试从当前点到起始点绘制一条直线
                        state.context.closePath();

                        saveImg();

                    }, false)

                }
            }, false)
        }

        function saveImg() {
            var oImg = new Image();
            if (state.showCanvas) {
                state.context.drawImage(oImg, 0, 0);
            }

            var ImgSrc = state.canvas.toDataURL('image/png');
            state.ImgSrc = ImgSrc;
            var params = {
                ImgSrc: state.ImgSrc,
                show: state.showCanvas
            }
            ctx.emit('setImgSrc', params)
        }

        function clearCanvas() {
            state.showCanvas = true;
            state.ImgSrc = ''
            var param = {
                show: state.showCanvas,
                ImgSrc: state.ImgSrc = ''
            }
            window.HBStorage.setData({'key': 'NewCheckSignName', 'value': param})

            if (props.show) {
                state.canvas.getContext('2d').clearRect(0, 0, state.canvas.width, state.canvas.height)
            } else {
                init()
            }
        }

        return {
            ...toRefs(state),
            saveImg,
            clearCanvas,
            init,
            testFun
        };
    },
});
</script>

好了,一个简单的签字功能就实现了