vue

canvas 签字画板 移动端及pc端

2021-11-25  本文已影响0人  alice_沉默如初

利用canvas,在移动端和pc端生成签字画板,签字并保存base64图片传给后端

html代码块

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no,minimal-ui">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="format-detection" content="email=no">
    <title>Title</title>
    <style>
        html,body{
            width: 100%;
            margin: 0;
            padding: 0;
        }
        body.popup-open {
            position: fixed;
        }
        .sign-dialog{
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.7);
            z-index: 8;
        }
        .sign-dialog .content{
            position: absolute;
            top: 50%;
            left: 50%;
            width: 80%;
            height: 320px;
            transform: translate(-50%,-50%);
            background: #fff;
            border-radius: 0.5rem;
            padding: 1rem;
            z-index: 2;
        }
        .sign-dialog .content h6{
            font-size: 0.75rem;
            margin:0;
            margin-bottom: 0.5rem;
        }
        .sign-dialog #canvasbox{
            border: 1px solid #333;
            border-radius: 0.8rem;
        }
        .sign-dialog .btns{
            /*display: flex;*/
            /*justify-content: end;*/
            margin-top: 0.5rem;
            text-align: right;
        }
        .sign-dialog .btns p{
            display: inline-block;
            width: 4rem;
            margin-left: 0.3rem;
            font-size: 0.9rem;
            line-height: 1.8rem;
            text-align: center;
            color: #fff;
            text-indent: 0;
            border-radius: 0.25rem;
            background: #d75c0a;
        }
    </style>
</head>
<body>
<div class="sign-dialog">
    <div class="content">
        <h6>签字:</h6>
        <canvas id="canvasbox" width="500" height="250"></canvas>
        <div class="btns">
            <p class="sign-clearbtn">清空</p>
            <p class="sign-savebtn">确定</p>
        </div>
    </div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script>
/*获取设备宽度,设置根字体大小*/
document.documentElement.style.fontSize = document.documentElement.clientWidth * 20 / 375 + "px";
window.onresize = function () {
    document.documentElement.style.fontSize = document.documentElement.clientWidth * 20 / 375 + "px";
}
$(function () {
    initPage.init();
})
var initPage = {
    init: function () {
        this.sign();
    },
    sign: function () {
        $('.img-wrap').click(function () {
            closeBodyScroll();
            $('.sign-dialog').show();
            let width = 300;
            let height = 200;
            if($('.sign-dialog .content')){
                width = $('.sign-dialog .content').width();
                height = $('.sign-dialog .content').height() * 0.7;
            }
            $('#canvasbox').attr('width',width)
            $('#canvasbox').attr('height',height)
            sign();
        })
        $('.sign-savebtn').click(function () {
            var canvasbox = document.getElementById("canvasbox");
            console.log(canvasbox.toDataURL("image/png"))
            clearCanvas();
            $('.sign-dialog').hide();
            openBodyScroll();
        })
        $('.sign-clearbtn').click(function () {
            clearCanvas();
        })
    }

}
function sign() {
    var canvasbox = document.getElementById("canvasbox");
    var ctx = canvasbox.getContext("2d");
    var iscanvas = false;
    let vertex = document.getElementById('canvasbox').getBoundingClientRect();
    if(checkBrowerType() === 'pc'){
        var offsetX = '';
        var offsetY = '';
        canvasbox.addEventListener("mousedown", function (e) {
            iscanvas = true;
            offsetX = e.offsetX;
            offsetY = e.offsetY;
        })
        canvasbox.addEventListener("mousemove", function (e) {
            if (iscanvas) {
                ctx.beginPath();
                ctx.moveTo(offsetX, offsetY)
                ctx.lineTo(e.offsetX, e.offsetY)
                ctx.lineWidth = 2;
                ctx.stroke()
                offsetX = e.offsetX;
                offsetY = e.offsetY;
            }
        })
        canvasbox.addEventListener("mouseup", function () {
            iscanvas = false;
        })
        canvasbox.addEventListener("mouseleave", function () {
            iscanvas = false;
        })
    }else{
        // 获取 canvas 相对于视口的位置。
        let vertex = document.getElementById('canvasbox').getBoundingClientRect();
        let t = vertex.top;
        let l = vertex.left
        canvasbox.addEventListener("touchstart", function (e) {
            e.preventDefault();
            iscanvas = true;
            ctx.beginPath();
            ctx.moveTo(e.changedTouches[0].clientX - l,e.changedTouches[0].clientY - t );
        })
        canvasbox.addEventListener("touchmove", function (e) {
            if (iscanvas) {
                ctx.lineTo(e.changedTouches[0].clientX - l,e.changedTouches[0].clientY - t );
                ctx.lineWidth = 2;
                ctx.lineJoin = 'round';
                ctx.stroke()
            }
        })
        canvasbox.addEventListener("touchend", function () {
            iscanvas = false;
            ctx.closePath();
        })
        canvasbox.addEventListener("touchcancel", function () {
            iscanvas = false;
            ctx.closePath();
        })
    }

}
//清空画板
function clearCanvas() {
    var canvasbox = document.getElementById("canvasbox");
    var ctx = canvasbox.getContext("2d");
    ctx.closePath();
    ctx.clearRect(0, 0, canvasbox.offsetWidth, canvasbox.offsetHeight);
}
//关闭body滚动轴
function closeBodyScroll() {
    window.lockMaskScrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    document.body.classList.add('popup-open');
    document.body.style.top = -window.lockMaskScrollTop + "px";
}
//打开body滚动轴
function openBodyScroll() {
    if (document.body.classList.contains('popup-open')) {
        document.body.classList.remove('popup-open');
        document.documentElement.scrollTop = window.lockMaskScrollTop;
    }
}
//判断 设备信息 是移动端还是pc端
function checkBrowerType() {
    var system = {
        win: false,
        mac: false,
        xll: false,
        ipad: false,
    };
    //检测平台
    var p = navigator.platform;
    system.win = p.indexOf("Win") == 0;
    system.mac = p.indexOf("Mac") == 0;
    system.x11 = p == "X11" || p.indexOf("Linux") == 0;
    system.ipad = navigator.userAgent.match(/iPad/i) != null ? true : false;
    if(system.win || system.mac || system.xll || system.ipad){
        return 'pc';
    }else{
        return 'mobile';
    }
}
</script>
</body>
</html>
上一篇下一篇

猜你喜欢

热点阅读