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>

效果图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值