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

前端代码

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 "保存失败";
            }
        }

结果展示

相关推荐
战族狼魂3 分钟前
基于SpringBoot+PostgreSQL+ROS Java库机器人数据可视化管理系统
java·spring boot·postgresql
半个脑袋儿10 分钟前
Java线程控制: sleep、yield、join深度解析
java
小智疯狂敲代码14 分钟前
Spring MVC-DispatcherServlet 的源码解析
java·面试
int0x0315 分钟前
Java中的内存"瘦身术":揭秘String Deduplication
java
半个脑袋儿15 分钟前
Java日期格式化中的“YYYY”陷阱:为什么跨年周会让你的年份突然+1?
java·后端
CHQIUU29 分钟前
Java 设计模式心法之第25篇 - 中介者 (Mediator) - 用“中央协调”降低对象间耦合度
java·设计模式·中介者模式
申城异乡人1 小时前
聊聊@Autowired与@Resource的区别
java·spring
爱编程的小新☆1 小时前
【MySQL】数据类型和表的操作
java·数据库·mysql
喝养乐多长不高1 小时前
详细PostMan的安装和基本使用方法
java·服务器·前端·网络协议·测试工具·https·postman