diff --git a/src/css/main.css b/src/css/main.css
index 57de4c1..39997c4 100644
--- a/src/css/main.css
+++ b/src/css/main.css
@@ -100,48 +100,4 @@ html, body {
.modal-dialog.modal-xxl {
max-width: 90vw;
}
-}
-
-select option {
- color: var(--bs-dark);
-}
-
-.alert {
- color: var(--bs-dark);
-}
-
-.theme-purple {
- background-image: linear-gradient(90deg,#33b7e2,#5e62b0,#dc307c);
-}
-
-.theme-green {
- background-image: linear-gradient(90deg, #9ebd13 0%, #008552 100%);
-}
-
-.theme-red {
- background-image: linear-gradient(90deg, #d53369 0%, #daae51 100%);
-}
-
-.theme-aqua {
- background-image: linear-gradient(90deg, #00d2ff 0%, #3a47d5 100%);
-}
-
-.theme-ocean {
- background-image: linear-gradient(90deg, #1CB5E0 0%, #000851 100%);
-}
-
-.theme-dusty {
- background-image: linear-gradient(90deg, #fcff9e 0%, #c67700 100%);
-}
-
-.theme-lilac {
- background-image: linear-gradient(90deg, #efd5ff 0%, #515ada 100%);
-}
-
-.theme-spring {
- background-image: linear-gradient(90deg, #00C9FF 0%, #92FE9D 100%);
-}
-
-.theme-shadow {
- background-image: linear-gradient(90deg, #4b6cb7 0%, #182848 100%);
}
\ No newline at end of file
diff --git a/src/css/theme.css b/src/css/theme.css
new file mode 100644
index 0000000..a9078d1
--- /dev/null
+++ b/src/css/theme.css
@@ -0,0 +1,54 @@
+/*
+Copyright 2021 Netsyms Technologies.
+This Source Code Form is subject to the terms of the Mozilla Public
+License, v. 2.0. If a copy of the MPL was not distributed with this
+file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+/*
+ Created on : Jul 17, 2021, 12:29:13 PM
+ Author : Skylar Ittner
+*/
+
+select option {
+ color: var(--bs-dark);
+}
+
+.alert {
+ color: var(--bs-dark);
+}
+
+.theme-purple {
+ background-image: linear-gradient(90deg,#33b7e2,#5e62b0,#dc307c);
+}
+
+.theme-green {
+ background-image: linear-gradient(90deg, #9ebd13 0%, #008552 100%);
+}
+
+.theme-red {
+ background-image: linear-gradient(90deg, #d53369 0%, #daae51 100%);
+}
+
+.theme-aqua {
+ background-image: linear-gradient(90deg, #00d2ff 0%, #3a47d5 100%);
+}
+
+.theme-ocean {
+ background-image: linear-gradient(90deg, #1CB5E0 0%, #000851 100%);
+}
+
+.theme-dusty {
+ background-image: linear-gradient(90deg, #fcff9e 0%, #c67700 100%);
+}
+
+.theme-lilac {
+ background-image: linear-gradient(90deg, #efd5ff 0%, #515ada 100%);
+}
+
+.theme-spring {
+ background-image: linear-gradient(90deg, #00C9FF 0%, #92FE9D 100%);
+}
+
+.theme-shadow {
+ background-image: linear-gradient(90deg, #4b6cb7 0%, #182848 100%);
+}
\ No newline at end of file
diff --git a/src/index.html b/src/index.html
index d98f6b6..0074003 100644
--- a/src/index.html
+++ b/src/index.html
@@ -10,6 +10,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
@@ -124,6 +125,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
Erase
Undo
+
Sign with Phone
@@ -139,6 +141,34 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+
+
Remote Signature Pad Connection
+
+
+
+
+
+ Use a phone, tablet, or other touchscreen device as a signature pad. It must be connected to the same network (e.g. WiFi hotspot) as this computer.
+ On the other device, go to the website shown below, or open a camera or barcode scanner app and point it the QR code shown.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -263,6 +293,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
@@ -273,4 +304,5 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/src/js/main.js b/src/js/main.js
index f0d918b..7214a9f 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -117,6 +117,63 @@ function activateNotarySignaturePad() {
};
}
+function signatureRemoteModalOpen() {
+ var url = getSignatureServerUrl();
+ $("#signatureRemoteUrlLabel").text(url);
+ new QRCode(document.getElementById("signatureRemoteQRCode"), url);
+ new bootstrap.Modal(document.getElementById('signatureRemoteModal')).show();
+}
+
+
+function handleRemoteSignatureData(data) {
+ if (!$("#signatureModal").hasClass("show")) {
+ return;
+ }
+ var canvas = document.getElementById("signaturecanvas");
+ signaturePad.fromData(scaleSignatureData(data, canvas.width, canvas.height));
+}
+
+function scaleSignatureData(data, width, height) {
+ // Get width and height of data
+ // Get the minimum positions too for adding a bit of margin
+ var oldwidth = 0;
+ var oldheight = 0;
+ var oldminX = 999999999;
+ var oldminY = 999999999;
+ for (var i = 0; i < data.length; i++) {
+ for (var j = 0; j < data[i].points.length; j++) {
+ oldwidth = Math.max(data[i].points[j].x, oldwidth);
+ oldheight = Math.max(data[i].points[j].y, oldheight);
+ oldminX = Math.min(data[i].points[j].x, oldminX);
+ oldminY = Math.min(data[i].points[j].y, oldminY);
+ }
+ }
+ var xPad = oldminX / 2;
+ var yPad = oldminY / 2;
+ // Calculate scale ratios
+ var scaleX = (oldwidth + xPad * 2) / width;
+ var scaleY = (oldheight + yPad * 2) / height;
+ // Pick the largest scale ratio and use only that one so it maintains aspect ratio
+ var scale = Math.max(scaleX, scaleY);
+ // Loop over the old data and scale the points into a new signature data object
+ var newdata = [];
+ for (var i = 0; i < data.length; i++) {
+ var newpoints = [];
+ for (var j = 0; j < data[i].points.length; j++) {
+ newpoints.push({
+ time: data[i].points[j].time,
+ x: (data[i].points[j].x + xPad) / scale,
+ y: (data[i].points[j].y + yPad) / scale
+ });
+ }
+ newdata.push({
+ color: data[i].color,
+ points: newpoints
+ });
+ }
+ return newdata;
+}
+
function trimAndShrinkSVG(svgstring) {
var div = document.getElementById('svgtrimbox');
div.innerHTML = svgstring;
diff --git a/src/js/sigserver.js b/src/js/sigserver.js
new file mode 100644
index 0000000..cd15d7d
--- /dev/null
+++ b/src/js/sigserver.js
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2021 Netsyms Technologies.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+const http_port = 36744; // dialed ENSIG on phone keypad (eNotary Signature)
+var http = require('http');
+var server = http.createServer(function (req, res) {
+ res.setHeader('Access-Control-Allow-Origin', '*');
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
+ if (req.method == "GET") {
+ console.log("Serving " + req.url);
+ switch (req.url) {
+ case "/":
+ res.writeHead(200, {'Content-Type': 'text/html'});
+ var index = getFileAsString("./sigserver/index.html");
+ index = index.replace("theme-BLANK", "theme-" + getStorage("color_theme"));
+ res.end(index);
+ break;
+ case "/bootstrap.min.css":
+ res.writeHead(200, {'Content-Type': 'text/css'});
+ res.end(getFileAsString("./css/bootstrap.min.css"));
+ break;
+ case "/theme.css":
+ res.writeHead(200, {'Content-Type': 'text/css'});
+ res.end(getFileAsString("./css/theme.css"));
+ break;
+ case "/fontawesome/all.min.js":
+ res.writeHead(200, {'Content-Type': 'text/javascript'});
+ res.end(getFileAsString("./node_modules/@fortawesome/fontawesome-free/js/all.min.js"));
+ break;
+ case "/signature_pad.umd.min.js":
+ res.writeHead(200, {'Content-Type': 'text/javascript'});
+ res.end(getFileAsString("./node_modules/signature_pad/dist/signature_pad.umd.min.js"));
+ break;
+ case "/img/signature-line.svg":
+ res.writeHead(200, {'Content-Type': 'image/svg+xml'});
+ res.end(getFileAsString("./img/signature-line.svg"));
+ break;
+ default:
+ res.writeHead(404);
+ res.end("404 not found.");
+ }
+ } else if (req.method == "POST") {
+ var body = '';
+ req.on('data', function (data) {
+ body += data;
+ });
+ req.on('end', function () {
+ handleRemoteSignatureData(JSON.parse(body));
+ });
+ res.writeHead(201);
+ }
+});
+server.listen(http_port); //3 - listen for any incoming requests
+console.log('Signature collection pad service running on port ' + http_port + '.');
+
+function getSignatureServerUrl() {
+ const prepareUrls = require('local-ip-url/prepareUrls');
+ var urls = prepareUrls({
+ protocol: 'http',
+ host: '0.0.0.0',
+ port: http_port
+ });
+ return urls.lanUrl;
+}
\ No newline at end of file
diff --git a/src/package-lock.json b/src/package-lock.json
index 6d2e9f3..0642a8f 100644
--- a/src/package-lock.json
+++ b/src/package-lock.json
@@ -488,6 +488,11 @@
"verror": "1.10.0"
}
},
+ "local-ip-url": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/local-ip-url/-/local-ip-url-1.0.3.tgz",
+ "integrity": "sha512-OyHVtNHgSmxr8B+6iA8sxlGrdNQJdr6M8db5/v83BdZA/cYe7+0i1XsyBQ0AoRj2nK32O3znEuPU9/b8TS6iww=="
+ },
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@@ -603,6 +608,11 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
+ "qrcodejs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/qrcodejs/-/qrcodejs-1.0.0.tgz",
+ "integrity": "sha1-r6tenoWFIfhZrjNtLtD5/S52zKc="
+ },
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
diff --git a/src/package.json b/src/package.json
index be80cc7..04b5009 100644
--- a/src/package.json
+++ b/src/package.json
@@ -25,9 +25,11 @@
"hasha": "^5.2.2",
"jquery": "^3.6.0",
"jspdf": "^2.3.1",
+ "local-ip-url": "^1.0.3",
"nwglobal": "0.0.2",
"opentimestamps": "^0.4.9",
"pdfjs-dist": "^2.8.335",
+ "qrcodejs": "^1.0.0",
"signature_pad": "^3.0.0-beta.4"
}
}
diff --git a/src/sigserver/index.html b/src/sigserver/index.html
new file mode 100644
index 0000000..ab4bc80
--- /dev/null
+++ b/src/sigserver/index.html
@@ -0,0 +1,114 @@
+
+
+
+
+ Signature Pad
+
+
+
+
+
+
+
+
+
+