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

JavaScript 创建一个简单的签名板

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JavaScript签名板</title>
    <link rel="stylesheet" href="styles.css" />
    <script src="https://cdn.jsdelivr.net/npm/signature_pad@4.1.7/dist/signature_pad.umd.min.js"></script>
  </head>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #f0f0f0;
      margin: 0;
    }

    .signature-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      width: 90%;
      max-width: 600px;
    }

    canvas {
      border: 1px solid#000;
      background-color: #fff;
      width: 100%;
      height: auto;
    }

    .controls {
      margin-top: 10px;
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
    }

    button {
      padding: 5px 10px;
      cursor: pointer;
    }
  </style>
  <body>
    <div class="signature-container">
      <canvas id="signature-pad" width="600" height="400"> </canvas>
      <div class="controls">
        <button id="undo">撤销</button>
        <button id="redo">重做</button>
        <button id="clear">清除</button>
        <button id="save-png">导出png格式</button>
        <button id="save-jpeg">导出jpeg格式</button>
      </div>
    </div>
    <script src="script.js"></script>
  </body>
  <script>
    document.addEventListener("DOMContentLoaded", function () {
      var canvas = document.getElementById("signature-pad");
      var signaturePad = new SignaturePad(canvas);
      var undoStack = [];
      var redoStack = [];
      function saveState() {
        undoStack.push(deepCopy(signaturePad.toData()));
        redoStack = [];
      }
      function undo() {
        if (undoStack.length > 0) {
          redoStack.push(deepCopy(signaturePad.toData()));
          undoStack.pop();
          signaturePad.clear();
          if (undoStack.length) {
            var lastStroke = undoStack[undoStack.length - 1];
            signaturePad.fromData(lastStroke, {
              clear: false,
            });
          }
        }
      }
      function redo() {
        if (redoStack.length > 0) {
          undoStack.push(deepCopy(signaturePad.toData()));
          var nextState = redoStack.pop();
          signaturePad.clear();
          if (nextState.length) {
            signaturePad.fromData(nextState);
          }
        }
      }
      document.getElementById("undo").addEventListener("click", undo);
      document.getElementById("redo").addEventListener("click", redo);
      document.getElementById("clear").addEventListener("click", function () {
        signaturePad.clear();
        undoStack = [];
        redoStack = [];
      });
      document
        .getElementById("save-png")
        .addEventListener("click", function () {
          if (!signaturePad.isEmpty()) {
            var dataURL = signaturePad.toDataURL("image/png");
            var link = document.createElement("a");
            link.href = dataURL;
            link.download = "signature.png";
            link.click();
          }
        });
      document
        .getElementById("save-jpeg")
        .addEventListener("click", function () {
          if (!signaturePad.isEmpty()) {
            var dataURL = signaturePad.toDataURL("image/jpeg");
            var link = document.createElement("a");
            link.href = dataURL;
            link.download = "signature.jpeg";
            link.click();
          }
        });
      // 绘图结束时保存状态
      signaturePad.addEventListener("endStroke", () => {
        console.log("Signature end");
        saveState();
      });
      // 初始画布设置
      function resizeCanvas() {
        var ratio = Math.max(window.devicePixelRatio || 1, 1);
        canvas.width = canvas.offsetWidth * ratio;
        canvas.height = canvas.offsetHeight * ratio;
        canvas.getContext("2d").scale(ratio, ratio);
        signaturePad.clear(); // 否则 isEmpty() 可能会返回错误值
        if (undoStack.length > 0) {
          signaturePad.fromData(undoStack[undoStack.length - 1]);
        }
      }
      function deepCopy(data) {
        return JSON.parse(JSON.stringify(data));
      }
      window.addEventListener("resize", resizeCanvas);
      resizeCanvas();
    });
  </script>
</html>

效果图


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

相关文章:

  • 【狂热算法篇】探秘图论之 Floyd 算法:解锁最短路径的神秘密码(通俗易懂版)
  • Windows图形界面(GUI)-QT-C/C++ - QT 对话窗口
  • C# 获取PDF文档中的字体信息(字体名、大小、颜色、样式等
  • “飞的”点外卖,科技新潮流来袭
  • 【混合开发】CefSharp+Vue 解决Cookie问题
  • ros2笔记-6.2 使用urdf创建机器人模型
  • 10 为什么系统需要引入分布式、微服务架构
  • 惠普M1005黑白激光打印机开机提示no print oartridge故障检修
  • 校园水电费管理小程序的设计与实现(LW+源码+讲解)
  • 云手机技术架构原理浅析,ARM架构与X86架构的对比
  • JavaScript语言的数据结构
  • 03JavaWeb——Ajax-Vue-Element(项目实战)
  • ubuntu的截图工具有哪些
  • 【机器学习实战入门】使用OpenCV和Keras的驾驶员疲劳检测系统
  • jenkins 入门到精通
  • cmake + vscode + mingw 开发环境配置
  • SystemUI 实现音量条同步功能
  • Python剪辑视频小妙招(moivepy库)
  • C#表达式和运算符
  • Ruby语言的网络编程
  • 递归算法学习v2.2
  • PyTorch和 torchvision 和torch 和cu1版本不匹配
  • centos 安全配置基线
  • 亲测解决CUDA error: device-side assert triggered
  • JVM之内存泄漏的详细解析
  • 处理 SQL Server 中的表锁问题