mirror of
				https://github.com/Frooodle/Stirling-PDF.git
				synced 2025-11-01 01:21:18 +01:00 
			
		
		
		
	Add on hover color to sign (#2059)
* Fixed layering issue with z-index, and added smoother transitions for… (#1996) Fixed layering issue with z-index, and added smoother transitions for signing Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> * Delete package-lock.json --------- Co-authored-by: Surya Karthikeyan Vijayalakshmi <108506548+SuryaKV101@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									04d5ae1912
								
							
						
					
					
						commit
						cae8cd0aa9
					
				@ -1,7 +1,9 @@
 | 
				
			|||||||
select#font-select,
 | 
					select#font-select,
 | 
				
			||||||
select#font-select option {
 | 
					select#font-select option {
 | 
				
			||||||
  height: 60px; /* Adjust as needed */
 | 
					  height: 60px;
 | 
				
			||||||
  font-size: 30px; /* Adjust as needed */
 | 
					  /* Adjust as needed */
 | 
				
			||||||
 | 
					  font-size: 30px;
 | 
				
			||||||
 | 
					  /* Adjust as needed */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.drawing-pad-container {
 | 
					.drawing-pad-container {
 | 
				
			||||||
@ -13,10 +15,12 @@ select#font-select option {
 | 
				
			|||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  height: 300px;
 | 
					  height: 300px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#box-drag-container {
 | 
					#box-drag-container {
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
  margin: 20px 0;
 | 
					  margin: 20px 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.draggable-buttons-box {
 | 
					.draggable-buttons-box {
 | 
				
			||||||
  position: absolute;
 | 
					  position: absolute;
 | 
				
			||||||
  top: 0;
 | 
					  top: 0;
 | 
				
			||||||
@ -24,16 +28,37 @@ select#font-select option {
 | 
				
			|||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  gap: 5px;
 | 
					  gap: 5px;
 | 
				
			||||||
 | 
					  z-index: 5;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.draggable-buttons-box>button {
 | 
					.draggable-buttons-box>button {
 | 
				
			||||||
  z-index: 10;
 | 
					  z-index: 4;
 | 
				
			||||||
  background-color: rgba(13, 110, 253, 0.1);
 | 
					  background-color: rgba(13, 110, 253, 0.1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.draggable-canvas {
 | 
					.draggable-canvas {
 | 
				
			||||||
  border: 1px solid red;
 | 
					  border: 2px solid #3498db;
 | 
				
			||||||
  position: absolute;
 | 
					  position: absolute;
 | 
				
			||||||
  touch-action: none;
 | 
					  touch-action: none;
 | 
				
			||||||
  user-select: none;
 | 
					  user-select: none;
 | 
				
			||||||
  top: 0px;
 | 
					  top: 0px;
 | 
				
			||||||
  left: 0;
 | 
					  left: 0;
 | 
				
			||||||
 | 
					  z-index: 100;
 | 
				
			||||||
 | 
					  cursor: grab;
 | 
				
			||||||
 | 
					  transition: transform 0.1s ease-out;
 | 
				
			||||||
 | 
					  background-color: rgba(52, 152, 219, 0.1);
 | 
				
			||||||
 | 
					  /* Light blue background */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.draggable-canvas:active {
 | 
				
			||||||
 | 
					  cursor: grabbing;
 | 
				
			||||||
 | 
					  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
 | 
				
			||||||
 | 
					  /* Shadow on active drag */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.draggable-canvas:hover {
 | 
				
			||||||
 | 
					  border: 2px solid #2980b9;
 | 
				
			||||||
 | 
					  /* Darker border on hover */
 | 
				
			||||||
 | 
					  background-color: rgba(52, 152, 219, 0.2);
 | 
				
			||||||
 | 
					  /* Darken background on hover */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										36
									
								
								src/main/resources/static/js/draggable.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/main/resources/static/js/draggable.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					const draggableElement = document.querySelector('.draggable-canvas');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Variables to store the current position of the draggable element
 | 
				
			||||||
 | 
					let offsetX, offsetY, isDragging = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					draggableElement.addEventListener('mousedown', (e) => {
 | 
				
			||||||
 | 
					  // Get the offset when the mouse is clicked inside the element
 | 
				
			||||||
 | 
					  offsetX = e.clientX - draggableElement.getBoundingClientRect().left;
 | 
				
			||||||
 | 
					  offsetY = e.clientY - draggableElement.getBoundingClientRect().top;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set isDragging to true
 | 
				
			||||||
 | 
					  isDragging = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Add event listeners for mouse movement and release
 | 
				
			||||||
 | 
					  document.addEventListener('mousemove', onMouseMove);
 | 
				
			||||||
 | 
					  document.addEventListener('mouseup', onMouseUp);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onMouseMove(e) {
 | 
				
			||||||
 | 
					  if (isDragging) {
 | 
				
			||||||
 | 
					    // Calculate the new position of the element
 | 
				
			||||||
 | 
					    const left = e.clientX - offsetX;
 | 
				
			||||||
 | 
					    const top = e.clientY - offsetY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Move the element by setting its style
 | 
				
			||||||
 | 
					    draggableElement.style.left = `${left}px`;
 | 
				
			||||||
 | 
					    draggableElement.style.top = `${top}px`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onMouseUp() {
 | 
				
			||||||
 | 
					  // Stop dragging and remove event listeners
 | 
				
			||||||
 | 
					  isDragging = false;
 | 
				
			||||||
 | 
					  document.removeEventListener('mousemove', onMouseMove);
 | 
				
			||||||
 | 
					  document.removeEventListener('mouseup', onMouseUp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,8 +1,11 @@
 | 
				
			|||||||
<!DOCTYPE html>
 | 
					<!DOCTYPE html>
 | 
				
			||||||
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
 | 
					<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}"
 | 
				
			||||||
 | 
					  xmlns:th="https://www.thymeleaf.org">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<head>
 | 
					<head>
 | 
				
			||||||
  <th:block th:insert="~{fragments/common :: head(title=#{sign.title}, header=#{sign.header})}"></th:block>
 | 
					  <th:block th:insert="~{fragments/common :: head(title=#{sign.title}, header=#{sign.header})}"></th:block>
 | 
				
			||||||
  <link rel="stylesheet" th:href="@{'/css/sign.css'}">
 | 
					  <link rel="stylesheet" th:href="@{'/css/sign.css'}">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <th:block th:each="font : ${fonts}">
 | 
					  <th:block th:each="font : ${fonts}">
 | 
				
			||||||
    <style th:inline="text">
 | 
					    <style th:inline="text">
 | 
				
			||||||
      @font-face {
 | 
					      @font-face {
 | 
				
			||||||
@ -11,13 +14,12 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      #font-select option[value="[[${font.name}]]"] {
 | 
					      #font-select option[value="[[${font.name}]]"] {
 | 
				
			||||||
        font-family: "[[${font.name}]]", cursive;
 | 
					        font-family: "[[${font.name}]]",
 | 
				
			||||||
      }
 | 
					        cursive;
 | 
				
			||||||
      #font-select option[value='/*[[${font.name}]]*/'] {
 | 
					 | 
				
			||||||
        font-family: '/*[[${font.name}]]*/', cursive;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    </style>
 | 
					    </style>
 | 
				
			||||||
  </th:block>
 | 
					  </th:block>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <script th:src="@{'/js/thirdParty/signature_pad.umd.min.js'}"></script>
 | 
					  <script th:src="@{'/js/thirdParty/signature_pad.umd.min.js'}"></script>
 | 
				
			||||||
  <script th:src="@{'/js/thirdParty/interact.min.js'}"></script>
 | 
					  <script th:src="@{'/js/thirdParty/interact.min.js'}"></script>
 | 
				
			||||||
</head>
 | 
					</head>
 | 
				
			||||||
@ -36,7 +38,9 @@
 | 
				
			|||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <!-- pdf selector -->
 | 
					            <!-- pdf selector -->
 | 
				
			||||||
              <div th:replace="~{fragments/common :: fileSelector(name='pdf-upload', multipleInputsForSingleRequest=false, disableMultipleFiles=true,  accept='application/pdf')}"></div>
 | 
					            <div
 | 
				
			||||||
 | 
					              th:replace="~{fragments/common :: fileSelector(name='pdf-upload', multipleInputsForSingleRequest=false, disableMultipleFiles=true, accept='application/pdf')}">
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
            <script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
 | 
					            <script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
 | 
				
			||||||
            <script>
 | 
					            <script>
 | 
				
			||||||
              let originalFileName = '';
 | 
					              let originalFileName = '';
 | 
				
			||||||
@ -45,30 +49,31 @@
 | 
				
			|||||||
                if (file) {
 | 
					                if (file) {
 | 
				
			||||||
                  originalFileName = file.name.replace(/\.[^/.]+$/, "");
 | 
					                  originalFileName = file.name.replace(/\.[^/.]+$/, "");
 | 
				
			||||||
                  const pdfData = await file.arrayBuffer();
 | 
					                  const pdfData = await file.arrayBuffer();
 | 
				
			||||||
                    pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs'
 | 
					                  pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
 | 
				
			||||||
                  const pdfDoc = await pdfjsLib.getDocument({ data: pdfData }).promise;
 | 
					                  const pdfDoc = await pdfjsLib.getDocument({ data: pdfData }).promise;
 | 
				
			||||||
                  await DraggableUtils.renderPage(pdfDoc, 0);
 | 
					                  await DraggableUtils.renderPage(pdfDoc, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  document.querySelectorAll(".show-on-file-selected").forEach(el => {
 | 
					                  document.querySelectorAll(".show-on-file-selected").forEach(el => {
 | 
				
			||||||
                    el.style.cssText = '';
 | 
					                    el.style.cssText = '';
 | 
				
			||||||
                    })
 | 
					                  });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              });
 | 
					              });
 | 
				
			||||||
              document.addEventListener("DOMContentLoaded", () => {
 | 
					              document.addEventListener("DOMContentLoaded", () => {
 | 
				
			||||||
                document.querySelectorAll(".show-on-file-selected").forEach(el => {
 | 
					                document.querySelectorAll(".show-on-file-selected").forEach(el => {
 | 
				
			||||||
                  el.style.cssText = "display:none !important";
 | 
					                  el.style.cssText = "display:none !important";
 | 
				
			||||||
                  })
 | 
					                });
 | 
				
			||||||
              });
 | 
					              });
 | 
				
			||||||
            </script>
 | 
					            </script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div class="tab-group show-on-file-selected">
 | 
					            <div class="tab-group show-on-file-selected">
 | 
				
			||||||
              <div class="tab-container" th:title="#{sign.upload}">
 | 
					              <div class="tab-container" th:title="#{sign.upload}">
 | 
				
			||||||
                  <div th:replace="~{fragments/common :: fileSelector(name='image-upload', multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}"></div>
 | 
					                <div
 | 
				
			||||||
 | 
					                  th:replace="~{fragments/common :: fileSelector(name='image-upload', multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}">
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
                <script>
 | 
					                <script>
 | 
				
			||||||
                  const imageUpload = document.querySelector('input[name=image-upload]');
 | 
					                  const imageUpload = document.querySelector('input[name=image-upload]');
 | 
				
			||||||
                  imageUpload.addEventListener('change', e => {
 | 
					                  imageUpload.addEventListener('change', e => {
 | 
				
			||||||
                        if(!e.target.files) {
 | 
					                    if (!e.target.files) return;
 | 
				
			||||||
                          return;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    for (const imageFile of e.target.files) {
 | 
					                    for (const imageFile of e.target.files) {
 | 
				
			||||||
                      var reader = new FileReader();
 | 
					                      var reader = new FileReader();
 | 
				
			||||||
                      reader.readAsDataURL(imageFile);
 | 
					                      reader.readAsDataURL(imageFile);
 | 
				
			||||||
@ -79,11 +84,14 @@
 | 
				
			|||||||
                  });
 | 
					                  });
 | 
				
			||||||
                </script>
 | 
					                </script>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              <div class="tab-container drawing-pad-container" th:title="#{sign.draw}">
 | 
					              <div class="tab-container drawing-pad-container" th:title="#{sign.draw}">
 | 
				
			||||||
                <canvas id="drawing-pad-canvas"></canvas>
 | 
					                <canvas id="drawing-pad-canvas"></canvas>
 | 
				
			||||||
                <br>
 | 
					                <br>
 | 
				
			||||||
                    <button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()" th:text="#{sign.clear}"></button>
 | 
					                <button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()"
 | 
				
			||||||
                    <button id="save-signature" class="btn btn-outline-success mt-2" onclick="addDraggableFromPad()" th:text="#{sign.add}"></button>
 | 
					                  th:text="#{sign.clear}"></button>
 | 
				
			||||||
 | 
					                <button id="save-signature" class="btn btn-outline-success mt-2" onclick="addDraggableFromPad()"
 | 
				
			||||||
 | 
					                  th:text="#{sign.add}"></button>
 | 
				
			||||||
                <script>
 | 
					                <script>
 | 
				
			||||||
                  const signaturePadCanvas = document.getElementById('drawing-pad-canvas');
 | 
					                  const signaturePadCanvas = document.getElementById('drawing-pad-canvas');
 | 
				
			||||||
                  const signaturePad = new SignaturePad(signaturePadCanvas, {
 | 
					                  const signaturePad = new SignaturePad(signaturePadCanvas, {
 | 
				
			||||||
@ -91,17 +99,17 @@
 | 
				
			|||||||
                    maxWidth: 2,
 | 
					                    maxWidth: 2,
 | 
				
			||||||
                    penColor: 'black',
 | 
					                    penColor: 'black',
 | 
				
			||||||
                  });
 | 
					                  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  function addDraggableFromPad() {
 | 
					                  function addDraggableFromPad() {
 | 
				
			||||||
                    if (signaturePad.isEmpty()) return;
 | 
					                    if (signaturePad.isEmpty()) return;
 | 
				
			||||||
                    const startTime = Date.now();
 | 
					                    const startTime = Date.now();
 | 
				
			||||||
                        const croppedDataUrl = getCroppedCanvasDataUrl(signaturePadCanvas)
 | 
					                    const croppedDataUrl = getCroppedCanvasDataUrl(signaturePadCanvas);
 | 
				
			||||||
                    console.log(Date.now() - startTime);
 | 
					                    console.log(Date.now() - startTime);
 | 
				
			||||||
                    DraggableUtils.createDraggableCanvasFromUrl(croppedDataUrl);
 | 
					                    DraggableUtils.createDraggableCanvasFromUrl(croppedDataUrl);
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                      function getCroppedCanvasDataUrl(canvas) {
 | 
					 | 
				
			||||||
                        // code is from: https://github.com/szimek/signature_pad/issues/49#issuecomment-1104035775
 | 
					 | 
				
			||||||
                        let originalCtx = canvas.getContext('2d');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  function getCroppedCanvasDataUrl(canvas) {
 | 
				
			||||||
 | 
					                    let originalCtx = canvas.getContext('2d');
 | 
				
			||||||
                    let originalWidth = canvas.width;
 | 
					                    let originalWidth = canvas.width;
 | 
				
			||||||
                    let originalHeight = canvas.height;
 | 
					                    let originalHeight = canvas.height;
 | 
				
			||||||
                    let imageData = originalCtx.getImageData(0, 0, originalWidth, originalHeight);
 | 
					                    let imageData = originalCtx.getImageData(0, 0, originalWidth, originalHeight);
 | 
				
			||||||
@ -135,10 +143,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    return croppedCanvas.toDataURL();
 | 
					                    return croppedCanvas.toDataURL();
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  function resizeCanvas() {
 | 
					                  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);
 | 
					                    var ratio = Math.max(window.devicePixelRatio || 1, 1);
 | 
				
			||||||
                    var additionalFactor = 10;
 | 
					                    var additionalFactor = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -146,31 +152,30 @@
 | 
				
			|||||||
                    signaturePadCanvas.height = signaturePadCanvas.offsetHeight * ratio * additionalFactor;
 | 
					                    signaturePadCanvas.height = signaturePadCanvas.offsetHeight * ratio * additionalFactor;
 | 
				
			||||||
                    signaturePadCanvas.getContext("2d").scale(ratio * additionalFactor, ratio * additionalFactor);
 | 
					                    signaturePadCanvas.getContext("2d").scale(ratio * additionalFactor, ratio * additionalFactor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        // This library does not listen for canvas changes, so after the canvas is automatically
 | 
					 | 
				
			||||||
                        // cleared by the browser, SignaturePad#isEmpty might still return false, even though the
 | 
					 | 
				
			||||||
                        // canvas looks empty, because the internal data of this library wasn't cleared. To make sure
 | 
					 | 
				
			||||||
                        // that the state of this library is consistent with visual state of the canvas, you
 | 
					 | 
				
			||||||
                        // have to clear it manually.
 | 
					 | 
				
			||||||
                    signaturePad.clear();
 | 
					                    signaturePad.clear();
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  new IntersectionObserver((entries, observer) => {
 | 
					                  new IntersectionObserver((entries, observer) => {
 | 
				
			||||||
                    if (entries.some(entry => entry.intersectionRatio > 0)) {
 | 
					                    if (entries.some(entry => entry.intersectionRatio > 0)) {
 | 
				
			||||||
                      resizeCanvas();
 | 
					                      resizeCanvas();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                  }).observe(signaturePadCanvas);
 | 
					                  }).observe(signaturePadCanvas);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  new ResizeObserver(resizeCanvas).observe(signaturePadCanvas);
 | 
					                  new ResizeObserver(resizeCanvas).observe(signaturePadCanvas);
 | 
				
			||||||
                </script>
 | 
					                </script>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              <div class="tab-container" th:title="#{sign.text}">
 | 
					              <div class="tab-container" th:title="#{sign.text}">
 | 
				
			||||||
                <label class="form-check-label" for="sigText" th:text="#{text}"></label>
 | 
					                <label class="form-check-label" for="sigText" th:text="#{text}"></label>
 | 
				
			||||||
                <textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
 | 
					                <textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
 | 
				
			||||||
                <label th:text="#{font}"></label>
 | 
					                <label th:text="#{font}"></label>
 | 
				
			||||||
                <select class="form-control" name="font" id="font-select">
 | 
					                <select class="form-control" name="font" id="font-select">
 | 
				
			||||||
                      <option th:each="font : ${fonts}" th:value="${font.name}" th:text="${font.name}" th:class="${font.name.toLowerCase()+'-font'}">
 | 
					                  <option th:each="font : ${fonts}" th:value="${font.name}" th:text="${font.name}"
 | 
				
			||||||
                      </option>
 | 
					                    th:class="${font.name.toLowerCase()+'-font'}"></option>
 | 
				
			||||||
                </select>
 | 
					                </select>
 | 
				
			||||||
                <div class="margin-auto-parent">
 | 
					                <div class="margin-auto-parent">
 | 
				
			||||||
                      <button id="save-text-signature" class="btn btn-outline-success mt-2 margin-center" onclick="addDraggableFromText()" th:text="#{sign.add}"></button>
 | 
					                  <button id="save-text-signature" class="btn btn-outline-success mt-2 margin-center"
 | 
				
			||||||
 | 
					                    onclick="addDraggableFromText()" th:text="#{sign.add}"></button>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <script>
 | 
					                <script>
 | 
				
			||||||
                  function addDraggableFromText() {
 | 
					                  function addDraggableFromText() {
 | 
				
			||||||
@ -203,27 +208,6 @@
 | 
				
			|||||||
                    DraggableUtils.createDraggableCanvasFromUrl(dataURL);
 | 
					                    DraggableUtils.createDraggableCanvasFromUrl(dataURL);
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                </script>
 | 
					                </script>
 | 
				
			||||||
                    <script>
 | 
					 | 
				
			||||||
                      const sigTextInput = document.getElementById('sigText');
 | 
					 | 
				
			||||||
                      const fontSelect = document.getElementById('font-select');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                      const updateOptionTexts = () => {
 | 
					 | 
				
			||||||
                        Array.from(fontSelect.options).forEach(option => {
 | 
					 | 
				
			||||||
                          const fontName = option.value.replace(/-regular$/i, '');
 | 
					 | 
				
			||||||
                          option.text = sigTextInput.value || fontName;
 | 
					 | 
				
			||||||
                        });
 | 
					 | 
				
			||||||
                      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                      sigTextInput.addEventListener('input', updateOptionTexts);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                      fontSelect.addEventListener('change', (e) => {
 | 
					 | 
				
			||||||
                        e.target.style.fontFamily = e.target.value;
 | 
					 | 
				
			||||||
                        updateOptionTexts();
 | 
					 | 
				
			||||||
                      });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                      // Manually trigger the change event
 | 
					 | 
				
			||||||
                      fontSelect.dispatchEvent(new Event('change'));
 | 
					 | 
				
			||||||
                  </script>
 | 
					 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -233,20 +217,31 @@
 | 
				
			|||||||
              <script th:src="@{'/js/thirdParty/pdf-lib.min.js'}"></script>
 | 
					              <script th:src="@{'/js/thirdParty/pdf-lib.min.js'}"></script>
 | 
				
			||||||
              <script th:src="@{'/js/draggable-utils.js'}"></script>
 | 
					              <script th:src="@{'/js/draggable-utils.js'}"></script>
 | 
				
			||||||
              <div class="draggable-buttons-box ignore-rtl">
 | 
					              <div class="draggable-buttons-box ignore-rtl">
 | 
				
			||||||
                  <button class="btn btn-outline-secondary" onclick="DraggableUtils.deleteDraggableCanvas(DraggableUtils.getLastInteracted())">
 | 
					                <button class="btn btn-outline-secondary"
 | 
				
			||||||
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
 | 
					                  onclick="DraggableUtils.deleteDraggableCanvas(DraggableUtils.getLastInteracted())">
 | 
				
			||||||
                      <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z"/>
 | 
					                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash"
 | 
				
			||||||
                      <path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z"/>
 | 
					                    viewBox="0 0 16 16">
 | 
				
			||||||
 | 
					                    <path
 | 
				
			||||||
 | 
					                      d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z" />
 | 
				
			||||||
 | 
					                    <path
 | 
				
			||||||
 | 
					                      d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z" />
 | 
				
			||||||
                  </svg>
 | 
					                  </svg>
 | 
				
			||||||
                </button>
 | 
					                </button>
 | 
				
			||||||
                  <button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.incrementPage() : DraggableUtils.decrementPage()" style="margin-left:auto">
 | 
					                <button class="btn btn-outline-secondary"
 | 
				
			||||||
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-left" viewBox="0 0 16 16">
 | 
					                  onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.incrementPage() : DraggableUtils.decrementPage()"
 | 
				
			||||||
                      <path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/>
 | 
					                  style="margin-left:auto">
 | 
				
			||||||
 | 
					                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
 | 
				
			||||||
 | 
					                    class="bi bi-chevron-left" viewBox="0 0 16 16">
 | 
				
			||||||
 | 
					                    <path fill-rule="evenodd"
 | 
				
			||||||
 | 
					                      d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z" />
 | 
				
			||||||
                  </svg>
 | 
					                  </svg>
 | 
				
			||||||
                </button>
 | 
					                </button>
 | 
				
			||||||
                  <button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.decrementPage() : DraggableUtils.incrementPage()">
 | 
					                <button class="btn btn-outline-secondary"
 | 
				
			||||||
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-right" viewBox="0 0 16 16">
 | 
					                  onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.decrementPage() : DraggableUtils.incrementPage()">
 | 
				
			||||||
                      <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/>
 | 
					                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
 | 
				
			||||||
 | 
					                    class="bi bi-chevron-right" viewBox="0 0 16 16">
 | 
				
			||||||
 | 
					                    <path fill-rule="evenodd"
 | 
				
			||||||
 | 
					                      d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z" />
 | 
				
			||||||
                  </svg>
 | 
					                  </svg>
 | 
				
			||||||
                </button>
 | 
					                </button>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
@ -254,7 +249,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            <!-- download button -->
 | 
					            <!-- download button -->
 | 
				
			||||||
            <div class="margin-auto-parent">
 | 
					            <div class="margin-auto-parent">
 | 
				
			||||||
                <button id="download-pdf" class="btn btn-primary mb-2 show-on-file-selected margin-center" th:text="#{downloadPdf}"></button>
 | 
					              <button id="download-pdf" class="btn btn-primary mb-2 show-on-file-selected margin-center"
 | 
				
			||||||
 | 
					                th:text="#{downloadPdf}"></button>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <script>
 | 
					            <script>
 | 
				
			||||||
@ -272,7 +268,12 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
 | 
					    <th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <!-- Link the draggable.js file -->
 | 
				
			||||||
 | 
					  <script src="/path/to/your/draggable.js"></script>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user