首页 > 其他分享 >JS实现电子签名,并且将带logo和时间水印的电子签名保存到本地

JS实现电子签名,并且将带logo和时间水印的电子签名保存到本地

时间:2023-09-22 15:24:59浏览次数:38  
标签:function canvas JS 电子签名 context addEventListener var logo event

页面效果如下

 本地保存的电子签名图片如下

 具体实现代码如下

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>电子签名</title>
    <style>
        #canvas {
            border: 1px solid #000;
            margin-bottom: 10px;
            margin-left: 50px;
        }

        button {
            width: 300px;
            height: 150px;
            font-size: 100px;
            margin-left: 50px;
        }

        h1 {
            margin-left: 50px;
        }

        p {
            margin-left: 50px;
        }
    </style>
</head>

<body>
<p><strong>电子签名</strong>-请在下方空白处签名:</p>
<canvas id="canvas" width="1000" height="600"></canvas>
<div>
    <button id="clearButton">清除</button>
    <button id="saveButton">保存</button>
</div>
<p><strong>仅在电脑端浏览器中点击保存按钮可以将电子签名保存到本地</strong></p>

<script>
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');
    var isDrawing = false;

    // 开始绘制签名
    function startDrawing(event) {
        isDrawing = true;
        if (event.type === 'touchstart') {
            context.beginPath();
            context.moveTo(event.touches[0].clientX - canvas.offsetLeft, event.touches[0].clientY - canvas.offsetTop);
        } else {
            context.beginPath();
            context.moveTo(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop);
        }
    }

    // 绘制签名
    function draw(event) {
        if (isDrawing) {
            event.preventDefault();
            if (event.type === 'touchmove') {
                context.lineTo(event.touches[0].clientX - canvas.offsetLeft, event.touches[0].clientY - canvas.offsetTop);
            } else {
                context.lineTo(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop);
            }
            context.stroke();
        }
    }

    // 停止绘制签名
    function stopDrawing() {
        isDrawing = false;
    }

    // 清除签名
    function clearCanvas() {
        context.clearRect(0, 0, canvas.width, canvas.height);
        // 重新加载logo
        drawWatermarkLogo();
    }

    drawWatermarkLogo();

    // 保存签名
    function saveSignature() {
        var fileName = getNowDateTime(true) + "_" + (Math.floor(Math.random() * 900) + 100);
        drawWatermarkDateTime(getNowDateTime(false), 'blue');
        // 创建临时链接并设置下载属性
        var link = document.createElement('a');
        link.href = canvas.toDataURL("image/png");
        link.download = fileName + '.png';
        // 触发链接点击事件
        link.click();
        alert("签名已保存!");
        // 清空
        clearCanvas();
    }

    // 在canvas上绘制日期时间水印
    function drawWatermarkDateTime(text, color) {
        context.font = '30px Arial';
        context.fillStyle = color;
        context.fillText(text, canvas.width - 300, canvas.height - 20);
    }

    // 在canvas上绘制logo水印
    function drawWatermarkLogo() {
        var image = new Image();
        // 当图像加载完成时,将其绘制到canvas上
        image.onload = function () {
            // 在canvas上绘制水印图像
            context.drawImage(image, 0, 0);
        };
        image.src = 'http://服务器IP/pic/xmj_logo.png'; // logo图像的路径
    }

    //获取当前日期时间  flag是否为纯数字
    function getNowDateTime(flag) {
        var date = new Date();
        var year = date.getFullYear();
        var month = ("0" + (date.getMonth() + 1)).slice(-2);
        var day = ("0" + date.getDate()).slice(-2);
        var hours = ("0" + date.getHours()).slice(-2);
        var minutes = ("0" + date.getMinutes()).slice(-2);
        var seconds = ("0" + date.getSeconds()).slice(-2);
        if (flag) {
            return year + month + day + hours + minutes + seconds;
        }
        return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
    }

    // 绑定事件监听器
    canvas.addEventListener('mousedown', startDrawing);
    canvas.addEventListener('mousemove', draw);
    canvas.addEventListener('mouseup', stopDrawing);
    canvas.addEventListener('mouseout', stopDrawing);
    canvas.addEventListener('touchstart', startDrawing);
    canvas.addEventListener('touchmove', draw);
    canvas.addEventListener('touchend', stopDrawing);

    var clearButton = document.getElementById('clearButton');
    clearButton.addEventListener('click', clearCanvas);

    var saveButton = document.getElementById('saveButton');
    saveButton.addEventListener('click', saveSignature);

</script>
</body>
</html>

 

标签:function,canvas,JS,电子签名,context,addEventListener,var,logo,event
From: https://www.cnblogs.com/xiaomaju/p/17722447.html

相关文章

  • @JsonFormat 使用方法
    @JsonFormat(shape=JsonFormat.Shape.STRING,pattern="yyyy-MM-ddHH:mm:ss",timezone="GMT+8")privateLocalDatecreateTime;错误示范:@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss")privateLocalDatecreateTime;@JsonFormat注解是一......
  • php js+laravel+mysql手术麻醉临床信息系统
    医院手麻系统源码 技术架构:phpjs+laravel+mysql vue2elementB/S网页版手术麻醉临床信息系统有着完善的临床业务功能,能够涵盖整个围术期的工作,能够采集、汇总、存储、处理、展现所有的临床诊疗资料。通过该系统的实施,能够规范麻醉科的工作流程,实现麻醉手术过程的信息数字......
  • JsonConvert相关操作
    #序列化时,忽略jsonproperty特性的作用:publicstaticclassJsonConvertExtension{publicstaticstringCustomSerialize(objectobj){JsonSerializerSettingssettings=newJsonSerializerSettings();settings.Formatting......
  • 一次性搞懂JS字符串截取方法substring()、slice()以及substr()的用法和区别
    substring()和slice()都接受两个参数,“start”和“end”。“start”表示截取的开始位置,“end”表示结束的位置(不包括该位置的字符,也就是前要后不要)。如果不传参数,则返回字符串本身的一个副本。 如果只传一个参数,则从该位置开始,截取到字符串的末尾。 如果传递两个参数,则......
  • 循环 JSONArray
    当需要遍历一个JSONArray时,可以使用Java中的循环结构来实现。以下是一个示例代码,演示如何使用Java循环遍历一个JSONArray: javaimportorg.json.JSONArray;importorg.json.JSONObject;publicclassJSONArrayExample{publicstaticvoidmain(String[]args){......
  • js 中 " + " 的使用
    //加法计算consta1=2+2//4letm1=5,m2='5'letn1=11,n2='11'letk1=70,k2='70'm1++//6(等价于m1=m1+1)m1++//6n1+=1//12(等价于n1=n1+1)n2+=1......
  • js jquery input radio点击事件
     HTML:<inputtype="radio"name="myname"value="1"/>1<inputtype="radio"name="myname"value="2"/>2 jquery代码: //点击事件change$('input[type=radio][name=myname]').ch......
  • EL表达式和JSTL标签库
    什么是EL表达式以及他的作用EL表达式和jsp表达式脚本输出对比a.jsp<%--CreatedbyIntelliJIDEA.User:SWTDate:2023/9/14Time:22:59TochangethistemplateuseFile|Settings|FileTemplates.--%><%@pagecontentType="text/html;charset=UTF-8......
  • JS实现任务队列
    引言假设有这么一个场景:前端订阅后台数据的变化,如果发生变化,则触发订阅回调;回调函数中,会执行一些耗时操作,如:请求接口,发送短信,存历史数据等;要求以上所有的操作都必须按照订阅触发的顺序执行;我们都知道,回调本身就是一种异步操作,我们仅仅依靠订阅回调无法保证回调中任务执行顺......
  • js加密双重保障之sm2国密
    前言 最近看到一些项目里边有用到sm2/3/4国密加密算法,这里给大家简单介绍一下。知识科普SM2(国密算法)是一种非对称加密算法,由中国国家密码管理局(NCC)制定,并被广泛应用于中国的信息安全领域。它基于椭圆曲线密码学,主要用于数字签名和数据加密。以下是SM2国密算法的一些关键特点:安全性:S......