Good morning everybody, I should develop a system to allow a client to sign a form through their smartphone, simply with the finger
In the past someone has asked for similar information but I have not found any specific advice.
The form could, in my opinion, behave in two ways:
-write information and then create an image from the user’s signature and upload by FTP
-or convert the image to base64, write it in the database and then have a way to reconvert it again and show it as jpg to the client.
I have never done anything like this and so I would like to know if any of you have had to face this problem.
Using asp.net on Windows servers and testing locally on IIS.
Thank you!
Hi Mark,
I recommend you explain the two ways again because it isn't easy to understand
Browsers can show base64-encoded images if that's what you're looking for, probably you just need a dmx-bind to bind the Base64 data to a certain attribute in the img tag
Sorry for my bad english!!!
I have found a solution for those who are interested.
I put in the form a field 'canvas' before 'submit'
<canvas id="signatureCanvas" width="400" height="200" class="border rounded w-100"></canvas>
<input type="hidden" id="firma_base64" name="firma">
then its JS code (thanks to ChatGPT )
<script>
document.addEventListener('DOMContentLoaded', function() {
const canvas = document.getElementById('signatureCanvas');
const ctx = canvas.getContext('2d');
const clearButton = document.getElementById('clearButton');
const firmaInput = document.getElementById('firma_base64');
const form = document.querySelector('form');
canvas.width = 800;
canvas.height = 300;
let isDrawing = false;
let hasSignature = false;
let lastX = 0;
let lastY = 0;
ctx.strokeStyle = '#000000';
ctx.lineWidth = 2;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
function getCoordinates(e) {
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
let clientX, clientY;
if (e.type.includes('touch')) {
clientX = e.touches[0].clientX;
clientY = e.touches[0].clientY;
} else {
clientX = e.clientX;
clientY = e.clientY;
}
return [
(clientX - rect.left) * scaleX,
(clientY - rect.top) * scaleY
];
}
function updateBase64() {
try {
const signatureData = canvas.toDataURL('image/png');
firmaInput.value = signatureData;
hasSignature = true;
console.log('Firma salvata:', signatureData.substring(0, 50) + '...');
} catch (error) {
console.error('Errore nel salvataggio della firma:', error);
}
}
function startDrawing(e) {
e.preventDefault();
isDrawing = true;
hasSignature = true;
[lastX, lastY] = getCoordinates(e);
}
function draw(e) {
if (!isDrawing) return;
e.preventDefault();
const [currentX, currentY] = getCoordinates(e);
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(currentX, currentY);
ctx.stroke();
[lastX, lastY] = [currentX, currentY];
// Aggiorna la firma durante il disegno
updateBase64();
}
function stopDrawing(e) {
if (isDrawing) {
isDrawing = false;
// Forza l'aggiornamento della firma quando si smette di disegnare
updateBase64();
}
}
// Event listeners per mouse
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
// Event listeners per touch
canvas.addEventListener('touchstart', startDrawing, { passive: false });
canvas.addEventListener('touchmove', draw, { passive: false });
canvas.addEventListener('touchend', stopDrawing);
canvas.addEventListener('touchcancel', stopDrawing);
// Previeni lo scroll
canvas.addEventListener('touchmove', function(e) {
e.preventDefault();
}, { passive: false });
// Pulisci canvas
clearButton.addEventListener('click', function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
firmaInput.value = '';
hasSignature = false;
});
// Controllo prima del submit
form.addEventListener('submit', function(e) {
if (hasSignature) {
// Forza un ultimo aggiornamento della firma prima del submit
updateBase64();
}
});
});
</script>
in the database is saved in image64 format, so in the view page I show it with:
<div align="center"><img dmx-bind:src="'data:image/jpeg;base64,'+data_detail1.data.firma" dmx-show="data_detail1.data.firma"></div>
1 Like