Debounce signature canvas to improve performance on mobile to fix firefox issues. Remove erroneous tooltips

This commit is contained in:
Reece Browne 2025-04-09 17:22:12 +12:00
parent 20b39847e6
commit d78f512d1c
2 changed files with 28 additions and 26 deletions

View File

@ -26,7 +26,6 @@ window.addEventListener("keydown", (event) => {
function undoDraw() {
const data = signaturePad.toData();
if (data && data.length > 0) {
const removed = data.pop();
undoData.push(removed);
@ -35,7 +34,6 @@ function undoDraw() {
}
function redoDraw() {
if (undoData.length > 0) {
const data = signaturePad.toData();
data.push(undoData.pop());
@ -52,24 +50,18 @@ function addDraggableFromPad() {
}
function getCroppedCanvasDataUrl(canvas) {
let originalCtx = canvas.getContext('2d');
let originalCtx = canvas.getContext('2d', { willReadFrequently: true });
let originalWidth = canvas.width;
let originalHeight = canvas.height;
let imageData = originalCtx.getImageData(0, 0, originalWidth, originalHeight);
let minX = originalWidth + 1,
maxX = -1,
minY = originalHeight + 1,
maxY = -1,
x = 0,
y = 0,
currentPixelColorValueIndex;
let minX = originalWidth + 1, maxX = -1, minY = originalHeight + 1, maxY = -1;
for (y = 0; y < originalHeight; y++) {
for (x = 0; x < originalWidth; x++) {
currentPixelColorValueIndex = (y * originalWidth + x) * 4;
let currentPixelAlphaValue = imageData.data[currentPixelColorValueIndex + 3];
if (currentPixelAlphaValue > 0) {
for (let y = 0; y < originalHeight; y++) {
for (let x = 0; x < originalWidth; x++) {
let idx = (y * originalWidth + x) * 4;
let alpha = imageData.data[idx + 3];
if (alpha > 0) {
if (minX > x) minX = x;
if (maxX < x) maxX = x;
if (minY > y) minY = y;
@ -81,14 +73,14 @@ function getCroppedCanvasDataUrl(canvas) {
let croppedWidth = maxX - minX;
let croppedHeight = maxY - minY;
if (croppedWidth < 0 || croppedHeight < 0) return null;
let cuttedImageData = originalCtx.getImageData(minX, minY, croppedWidth, croppedHeight);
let cutImageData = originalCtx.getImageData(minX, minY, croppedWidth, croppedHeight);
let croppedCanvas = document.createElement('canvas'),
croppedCtx = croppedCanvas.getContext('2d');
let croppedCanvas = document.createElement('canvas');
let croppedCtx = croppedCanvas.getContext('2d');
croppedCanvas.width = croppedWidth;
croppedCanvas.height = croppedHeight;
croppedCtx.putImageData(cuttedImageData, 0, 0);
croppedCtx.putImageData(cutImageData, 0, 0);
return croppedCanvas.toDataURL();
}
@ -114,10 +106,20 @@ function resizeCanvas() {
signaturePad.clear();
}
new IntersectionObserver((entries, observer) => {
const debounce = (fn, delay = 100) => {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
};
const debouncedResize = debounce(resizeCanvas, 200);
new IntersectionObserver((entries) => {
if (entries.some((entry) => entry.intersectionRatio > 0)) {
resizeCanvas();
debouncedResize();
}
}).observe(signaturePadCanvas);
new ResizeObserver(resizeCanvas).observe(signaturePadCanvas);
new ResizeObserver(debouncedResize).observe(signaturePadCanvas);

View File

@ -43,13 +43,13 @@
</div>
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
<div class="tab-group show-on-file-selected">
<div class="tab-container" th:title="#{sign.upload}" th:data-title="#{sign.upload}">
<div class="tab-container"th:data-title="#{sign.upload}">
<div
th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=false, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}">
</div>
</div>
<div class="tab-container drawing-pad-container" th:title="#{sign.draw}" th:data-title="#{sign.draw}">
<div class="tab-container drawing-pad-container" th:data-title="#{sign.draw}">
<canvas id="drawing-pad-canvas"></canvas>
<br>
<button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()"
@ -62,7 +62,7 @@
onclick="redoDraw()"></button>
</div>
<div class="tab-container" th:title="#{sign.saved}" th:data-title="#{sign.saved}">
<div class="tab-container" th:data-title="#{sign.saved}">
<div class="saved-signatures-section" th:if="${not #lists.isEmpty(signatures)}">
<!-- Preview Modal -->
@ -134,7 +134,7 @@
</div>
</div>
<div class="tab-container" th:title="#{sign.text}" th:data-title="#{sign.text}">
<div class="tab-container" th:data-title="#{sign.text}">
<label class="form-check-label" for="sigText" th:text="#{text}"></label>
<textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
<label th:text="#{font}"></label>