SignaturePad undo feature
by HugeHugh
HTML
<script src="https://szimek.github.io/signature_pad/js/signature_pad.umd.js"></script>
<div class="wrapper">
<canvas id="signature-pad" class="signature-pad" width=400 height=200></canvas>
</div>
<button id="undo">Undo</button>
<button id="clear">Clear</button>
<div id="counter">
Strokes: 0
</div>
CSS
.wrapper {
position: relative;
width: 400px;
height: 200px;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
.signature-pad {
position: absolute;
left: 0;
top: 0;
width:400px;
height:200px;
background-color: white;
}
#counter {
margin-top: 3em;
}
JavaScript
var startSig = 'https://ourlostfounding.com/wp-content/uploads/2017/01/John-Hancock-signature-1024x287.png'
var canvas = document.getElementById('signature-pad');
var counter = document.getElementById('counter');
// Adjust canvas coordinate space taking into account pixel ratio,
// to make it look crisp on mobile devices.
// This also causes canvas to be cleared.
function resizeCanvas() {
// When zoomed out to less than 100%, for some very strange reason,
// some browsers report devicePixelRatio as less than 1
// and only part of the canvas is cleared then.
var ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext("2d").scale(ratio, ratio);
}
window.onresize = resizeCanvas;
resizeCanvas();
var signaturePad = new SignaturePad(canvas, {
onEnd: () => {
const data = signaturePad.toData();
updateCounter(data);
},
backgroundColor: 'rgb(255, 255, 255)' // necessary for saving image as JPEG; can be removed is only saving as PNG or SVG
});
function updateCounter(data) {
const display = "Strokes: " + data.length;
counter.innerHTML = display;
}
signaturePad.fromDataURL(startSig);
document.getElementById('clear').addEventListener('click', function () {
signaturePad.clear();
startSig = null;
updateCounter([]);
});
document.getElementById('undo').addEventListener('click', function () {
var data = signaturePad.toData();
if (data && data.length) {
data.pop(); // remove the last dot or line
} else if (startSig) {
startSig = null;
}
signaturePad.clear();
if (startSig) {
signaturePad.fromDataURL(startSig, {}, () => afterInit(data));
} else {
afterInit(data);
}
updateCounter(data);
});
function afterInit(data) {
if (data && data.length > 0) {
signaturePad._fromData(
data,
({ color, curve }) => this.signaturePad._drawCurve({ color, curve }),
({ color, point }) =>...