.signature-wrapper {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
max-width: 420px;
margin: 0 auto;
text-align: center;
}
h3 {
color: #374151;
}
canvas {
background: #fff;
border: 2px dashed #d1d5db;
border-radius: 12px;
cursor: crosshair;
touch-action: none;
}
.sig-controls {
margin-top: 15px;
display: flex;
justify-content: center;
gap: 10px;
}
button {
padding: 8px 20px;
border: 1px solid #d1d5db;
background: white;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
color: #374151;
}
button.save {
background: #2563eb;
color: white;
border-color: #2563eb;
}
button:hover {
opacity: 0.9;
}
const canvas = document.getElementById("sig-canvas");
const ctx = canvas.getContext("2d");
let writingMode = false;
ctx.lineWidth = 2;
ctx.lineJoin = "round";
ctx.lineCap = "round";
ctx.strokeStyle = "#1f2937";
const getTargetPosition = (e) => {
const rect = canvas.getBoundingClientRect();
if (e.touches) {
return {
x: e.touches[0].clientX - rect.left,
y: e.touches[0].clientY - rect.top
};
}
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
};
const handlePointerMove = (e) => {
if (!writingMode) return;
e.preventDefault();
const { x, y } = getTargetPosition(e);
ctx.lineTo(x, y);
ctx.stroke();
};
const handlePointerUp = () => {
writingMode = false;
ctx.closePath();
};
const handlePointerDown = (e) => {
writingMode = true;
ctx.beginPath();
const { x, y } = getTargetPosition(e);
ctx.moveTo(x, y);
e.preventDefault();
};
canvas.addEventListener("mousedown", handlePointerDown);
canvas.addEventListener("touchstart", handlePointerDown);
canvas.addEventListener("mouseup", handlePointerUp);
canvas.addEventListener("touchend", handlePointerUp);
canvas.addEventListener("mousemove", handlePointerMove);
canvas.addEventListener("touchmove", handlePointerMove);
document.getElementById("clearBtn").addEventListener("click", () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
});