其他分享
首页 > 其他分享> > vue实现用canvas写的手写签名组件

vue实现用canvas写的手写签名组件

作者:互联网

signature.vue组件的内容

<template>
    <div class="signature">
        <div class="title">请在虚线方框内签名</div>
        <canvas
                ref="canvas"
                id="canvas">签名区域</canvas>
        <div class="canvas-btn">
            <button class="primary" @click="save('signature')">保存</button>
            <button class="danger" @click="clear">清除</button>
        </div>
    </div>
</template>

<script>
    let draw;
    let canvasWidth;
    let canvasHeight;
    let preHandler = function(e) {
        if(e.preventDefault){
            e.preventDefault();
        }else{
            e.returnValue = false;
        }
    };

    var meta = document.createElement('meta');
    meta.content = 'portrait';
    document.getElementsByTagName('head')[0].appendChild(meta);

    //获取当前屏幕的宽高
    function getWindowSize(){
        canvasWidth = document.documentElement.clientWidth - 40;
        if(!canvasWidth){
            return;
        }
        hengshuping();
    }

    //判断手机横竖屏状态:
    function hengshuping(){
        if(window.orientation==180||window.orientation==0){
            // alert("竖屏状态!")
            canvasHeight = document.documentElement.clientHeight - document.documentElement.clientHeight / 1.4;
        }
        if(window.orientation==90||window.orientation==-90){
            // alert("横屏状态!")
            canvasHeight = document.documentElement.clientHeight - 63;
        }
    }

    getWindowSize();

    window.onresize = function(){
        getWindowSize();
        draw = {};
        draw = new Draw("canvas");
        draw.init();
    };

    class Draw {
        constructor(el){
            if(!canvasWidth){return;}
            console.log(canvasWidth);
            this.el = el;
            this.canvas = document.getElementById(this.el);
            if(!this.canvas){return;}
            this.canvas.width = canvasWidth;
            this.canvas.height = canvasHeight;
            this.cxt = this.canvas.getContext("2d");
            this.stageInfo = canvas.getBoundingClientRect();
            this.path = {
                beginX: 0,
                beginY: 0,
                endX: 0,
                endY: 0
            };
        }
        init(btn){
            if(!this.canvas){
                return;
            }
            this.canvas.addEventListener("touchstart", event => {
                document.addEventListener("touchstart", preHandler, {passive: false});
                this.drawBegin(event);
            }, {passive: false});
            this.canvas.addEventListener("touchend", event => {
                document.addEventListener("touchend", preHandler, {passive: false});
                this.drawEnd();
            }, {passive: false});
            this.clear(btn);
        }
        drawBegin(e){
            window.getSelection()
                ? window.getSelection().removeAllRanges()
                : document.selection.empty();
            this.cxt.strokeStyle = "#000";
            this.cxt.beginPath();
            this.cxt.moveTo(
                e.changedTouches[0].clientX - this.stageInfo.left,
                e.changedTouches[0].clientY - this.stageInfo.top
            );
            this.path.beginX = e.changedTouches[0].clientX - this.stageInfo.left;
            this.path.beginY = e.changedTouches[0].clientY - this.stageInfo.top;
            canvas.addEventListener("touchmove", ()=>{
                this.drawing(event);
            }, {passive: false});
        }
        drawing(e){
            this.cxt.lineTo(
                e.changedTouches[0].clientX - this.stageInfo.left,
                e.changedTouches[0].clientY - this.stageInfo.top
            );
            this.path.endX = e.changedTouches[0].clientX - this.stageInfo.left;
            this.path.endY = e.changedTouches[0].clientY - this.stageInfo.top;
            this.cxt.stroke();
        }
        checkCanvas(){
            var blank = document.createElement('canvas');
            blank.width = canvas.width;
            blank.height = canvas.height;
            return canvas.toDataURL() == blank.toDataURL();
        }
        drawEnd(){
            document.removeEventListener("touchstart", preHandler, false);
            document.removeEventListener("touchend", preHandler, false);
            document.removeEventListener("touchmove", preHandler, false);
        }
        clear(){
            this.cxt.clearRect(0, 0, canvasWidth, canvasHeight);
        }
        save(fileName){
            let imgURL = canvas.toDataURL('image/png');
            return imgURL;
        }
    }
    export default {
        props: {
            show: {default:false},
        },

        mounted(){
            draw = new Draw("canvas");
            draw.init();
        },

        methods: {
            clear: function(){
                draw.clear();
            },
            save: function(fileName){
                let data = draw.save(fileName);
                if(draw.checkCanvas()){
                    alert('请签名');
                    return;
                }

                this.$emit('signature', data);
                this.clear();
            },
        },
        watch: {
            show(){
                if(this.show){
                    document.getElementsByClassName('signaturePanel')[0].style = 'z-index:1000';
                }else{
                    document.getElementsByClassName('signaturePanel')[0].style = 'z-index:-100';
                }
            }
        }
    }
</script>

<style lang="scss">
    .signature {
        position: relative;
        text-align: right;
        top: 10px;
        padding-right: 10px;
        .title {
            display: inline-block;
            width: 20px;
            vertical-align: top;
            text-align: center;
        }
    }
    #canvas {
        border: 1px dashed #ccc;
        background: #fff;
        display: inline-block;
    }
    .canvas-btn {
        margin-top: 10px;
        font-size: 0;
        position: fixed;
        width: 100%;
        button {
            padding: 10px;
            width: 50%;
        }
    }

    * {
        touch-action: pan-y;
    }
</style>

 

标签:canvas,stageInfo,false,draw,vue,changedTouches,手写,document
来源: https://blog.csdn.net/wsaku/article/details/101057778