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>
效果图