Skip to content

Commit e2e70a8

Browse files
Signature pad widget (#2472)
* Create README.md Explains the features of the widget. * Create HTML File.html Defines the visual structure of the signature pad. It includes a <canvas> for drawing and two buttons for clearing or attaching the signature. * Create Client Controller.js Handles the logic for drawing on the canvas, capturing mouse/touch input, clearing the signature, and converting it into a Base64-encoded image for further processing.
1 parent 4ddef2b commit e2e70a8

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
api.controller = function($scope) {
2+
var c = this;
3+
var canvas, ctx;
4+
var drawing = false;
5+
var lastPos = { x: 0, y: 0 };
6+
7+
// Initialize after DOM is ready
8+
c.$onInit = function() {
9+
setTimeout(function() {
10+
canvas = document.getElementById('signature-pad');
11+
if (!canvas) return;
12+
13+
// Get 2D drawing context
14+
ctx = canvas.getContext('2d');
15+
ctx.lineWidth = 2;
16+
ctx.strokeStyle = '#000';
17+
18+
// Mouse event listeners
19+
canvas.addEventListener('mousedown', startDraw);
20+
canvas.addEventListener('mousemove', draw);
21+
canvas.addEventListener('mouseup', endDraw);
22+
23+
// Touch event listeners (for mobile/tablet)
24+
canvas.addEventListener('touchstart', startDraw);
25+
canvas.addEventListener('touchmove', draw);
26+
canvas.addEventListener('touchend', endDraw);
27+
}, 200);
28+
};
29+
30+
// Get drawing position based on mouse or touch input
31+
function getPosition(event) {
32+
var rect = canvas.getBoundingClientRect();
33+
if (event.touches && event.touches[0]) {
34+
return {
35+
x: event.touches[0].clientX - rect.left,
36+
y: event.touches[0].clientY - rect.top
37+
};
38+
}
39+
return {
40+
x: event.clientX - rect.left,
41+
y: event.clientY - rect.top
42+
};
43+
}
44+
45+
// Start drawing when mouse/touch pressed
46+
function startDraw(e) {
47+
drawing = true;
48+
lastPos = getPosition(e);
49+
}
50+
51+
// Draw line on canvas while dragging
52+
function draw(e) {
53+
if (!drawing) return;
54+
e.preventDefault(); // Prevent page scrolling on touch
55+
var pos = getPosition(e);
56+
ctx.beginPath();
57+
ctx.moveTo(lastPos.x, lastPos.y);
58+
ctx.lineTo(pos.x, pos.y);
59+
ctx.stroke();
60+
lastPos = pos;
61+
}
62+
63+
// Stop drawing when mouse/touch released
64+
function endDraw() {
65+
drawing = false;
66+
}
67+
68+
// Clear the canvas
69+
c.clearSignature = function() {
70+
if (ctx) ctx.clearRect(0, 0, canvas.width, canvas.height);
71+
drawing = false;
72+
};
73+
74+
// Convert signature to base64 image and attach
75+
c.attachSignature = function() {
76+
if (!ctx) return alert("Canvas not initialized.");
77+
var data = canvas.toDataURL('image/png'); // Get base64 encoded image
78+
alert("Signature captured successfully. It will be attached after submission.\n\n" + data);
79+
};
80+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div class="text-center">
2+
<!-- Canvas area for drawing signature -->
3+
<canvas id="signature-pad" width="400" height="200"
4+
style="border:1px solid #ccc; border-radius:8px; cursor:crosshair; touch-action:none;">
5+
</canvas>
6+
7+
<!-- Action buttons -->
8+
<div class="mt-3">
9+
<button class="btn btn-primary" ng-click="c.clearSignature()">Clear</button>
10+
<button class="btn btn-success" ng-click="c.attachSignature()">Attach Signature</button>
11+
</div>
12+
</div>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
A lightweight ServiceNow Service Portal widget that allows users to draw, clear, and attach signatures using a <canvas> element, compatible with both desktop and mobile devices.
2+
3+
Features
4+
5+
Draw signature using mouse or touch input.
6+
7+
Clear the signature pad with one click.
8+
9+
Convert the signature to a Base64 PNG string for storage or submission.
10+
11+
No external dependencies (pure JavaScript & HTML5 Canvas).

0 commit comments

Comments
 (0)