当前位置: 首页 > article >正文

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

前端代码

<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>

后端代码

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

结果展示

 


http://www.kler.cn/a/427481.html

相关文章:

  • 【Spark】 groupByKey与reduceByKey的区别
  • Conda-Pack打包:高效管理Python环境
  • 安全生产培训题库200道;免费题库;大风车题库
  • ArrayList 底层结构和源码分析/注意事项
  • 基于Java Springboot环境保护生活App且微信小程序
  • 代码随想录-算法训练营day42(动态规划05:最后一块石头的重量2,目标和,一和零)
  • AttributeError: module numpy has no attribute int .报错解决
  • API设计指南:详解HTTP状态码错误解析、HTTP方法及参数命名规则
  • Uniapp的vue、nvue、uvue后缀名区别
  • CSS 实现视差滚动:详解 background-attachment 与 transform:translate3D 及应用
  • matlab Delaunay三角剖分提取平面点云的边界
  • 【随笔笔记】将mysql数据迁移到群晖NAS
  • 阿拉丁论文助手:一键点亮学术之路
  • 仿真键盘输入遇到Edge环境不识别 回车符如何处理
  • PHP使用RabbitMQ(正常连接与开启SSL验证后的连接)
  • 零基础学鸿蒙开发--第九篇--网络请求
  • lvgl9 消息框控件Message(lv_message)使用指南
  • macOS 15.1.1 (24B2091) 系统中快捷键符号及其代表的按键的对照表
  • 学习23种设计模式
  • 刷算法心得