手写电子签名并保存到当前项目下

前端代码

javascript 复制代码
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>手写电子签名</title>
    <style>
        canvas {
            border: 1px solid #000 ;
        }
        button {
            margin-top: 10px;
        }
    </style>
</head>
<body>
<canvas id="signatureCanvas" width="400" height="200"></canvas>
<button onclick="clearCanvas()">重新输入签名</button>
<button onclick="saveSignature()">保存签名</button>

<script>
    // 获取页面上的canvas元素,这个元素用于绘制签名
    const canvas = document.getElementById('signatureCanvas');

    // 获取canvas的2D绘图上下文,用于在canvas上进行绘图操作
    const ctx = canvas.getContext('2d');

    // 定义一个变量来跟踪当前是否正在绘图
    let isDrawing = false;

    // 定义变量来存储上一个点的坐标,用于绘制线条
    let lastX = 0;
    let lastY = 0;

    // 当鼠标按下时触发的事件监听器
    canvas.addEventListener('mousedown', (e) => {
        // 设置isDrawing为true,表示开始绘图
        isDrawing = true;
        // 使用解构赋值更新lastX和lastY为鼠标当前的位置
        [lastX, lastY] = [e.offsetX, e.offsetY];
    });

    // 当鼠标移动时触发的事件监听器
    canvas.addEventListener('mousemove', (e) => {
        // 如果正在绘图,则执行以下操作
        if (isDrawing) {
            // 开始一个新的路径
            ctx.beginPath();
            // 将路径的起点移动到上一个点的坐标
            ctx.moveTo(lastX, lastY);
            // 将路径的终点设置为当前鼠标的位置
            ctx.lineTo(e.offsetX, e.offsetY);
            // 描边路径,使线条可见
            ctx.stroke();
            // 更新lastX和lastY为当前鼠标的位置,为下一次绘制准备
            [lastX, lastY] = [e.offsetX, e.offsetY];
        }
    });

    // 当鼠标松开时触发的事件监听器
    canvas.addEventListener('mouseup', () => {
        // 设置isDrawing为false,表示停止绘图
        isDrawing = false;
    });

    // 定义一个函数用于清空canvas上的内容
    function clearCanvas() {
        // 使用clearRect方法清空canvas上的所有内容
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    }

    // 定义一个函数用于保存签名到服务器
    function saveSignature() {
        // 将canvas的内容转换为DataURL格式的字符串,这个字符串包含了图像的base64编码
        const imageDataUrl = canvas.toDataURL();
        // 从imageDataUrl中提取出base64编码的图像数据
        const imageData = imageDataUrl.substring("data:image/png;base64,".length);
        // 调用sendDataToServer函数将图像数据发送到服务器
        sendDataToServer(imageData);
    }

    // 定义一个函数用于通过XMLHttpRequest将数据发送到服务器
    function sendDataToServer(imageDataUrl) {
        // 创建一个新的XMLHttpRequest对象
        const xhr = new XMLHttpRequest();
        // 配置xhr对象,设置请求方法为POST,请求URL为'/one/saveSignature',并设置为异步请求
        xhr.open('POST', '/one/saveSignature', true);
        // 设置请求头Content-Type为application/json,表示发送的数据是JSON格式
        xhr.setRequestHeader('Content-Type', 'application/json');
        // 设置xhr的onload事件处理函数,用于处理响应
        xhr.onload = function () {
            // 如果响应状态码为200,表示请求成功,打印响应文本
            if (xhr.status === 200) {
                console.log(xhr.responseText);
            } else {
                // 如果响应状态码不是200,打印错误信息
                console.error('Error:', xhr.statusText);
            }
        };
        // 发送请求,请求体是一个JSON对象,包含一个名为imageData的属性,其值为base64编码的图像数据
        xhr.send(JSON.stringify({imageData: imageDataUrl}));
    }
</script>
</body>
</html>

后端代码

java 复制代码
@ApiOperation(value = "电子签名图片", notes = "电子签名图片")//接口释义
    @RequestMapping(value = "/saveSignature", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "imageData", value = "base64", required = true)
    })
    public String saveSignature(@RequestBody String imageData,HttpServletRequest request) {
        // 创建日期格式器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd/");
        // 格式化日期
        String formattedDate = LocalDate.now().format(formatter);
        // 压缩临时目录
        String tmpdir = request.getSession().getServletContext().getRealPath("/") + "files/sign/" + formattedDate;
        if (!FileUtil.exist(new File(tmpdir))) {
            FileUtil.mkdir(tmpdir);
        }
            try {
                // 尝试解码Base64字符串
                byte[] imageBytes = Base64.getDecoder().decode(JSONObject.parseObject(imageData).getString("imageData"));
                // 保存图片到指定路径
                File imageFile = new File(tmpdir + UUID.randomUUID() + ".png");
                FileOutputStream outputStream = new FileOutputStream(imageFile);
                outputStream.write(imageBytes);
                outputStream.close();
                // 返回保存成功的信息
                return "保存成功" + imageFile.getPath();
            } catch (Exception e) {
                e.printStackTrace();
                return "保存失败";
            }
        }

结果展示

相关推荐
Paddy哥5 分钟前
jsmpeg+java+ffmpeg 调用摄像头RTSP流播放
java·开发语言·ffmpeg
oioihoii28 分钟前
C++23 新增扁平化关联容器详解
java·开发语言·c++23
IT从业者张某某41 分钟前
信奥赛-刷题笔记-栈篇-T2-P1165日志分析0519
android·java·笔记
asom221 小时前
Java 04 API
java·开发语言
qq_214225871 小时前
学生成绩管理系统Java实战(Spring Boot+MyBatis Plus)
java·spring boot·其他·mybatis
吗喽对你问好1 小时前
23种设计模式解释+记忆
java·设计模式
188_djh1 小时前
# 终端执行 java -jar example.jar 时(example.jar为项目jar包)报错:“没有主清单属性” 的解决方法
java·pycharm·jar·cmd·没有主清单属性·java -jar
CodeClimb2 小时前
【华为OD-B卷-打印文件 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
C182981825752 小时前
Rocketmq刷盘机制和复制机制区别及关系
java·rocketmq·java-rocketmq
D.eL2 小时前
设计模式7大原则与UML类图详解
java·设计模式·uml