Skip to content
Closed
44 changes: 31 additions & 13 deletions src/main/resources/static/css/sign.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
select#font-select,
select#font-select option {
height: 60px; /* Adjust as needed */
font-size: 30px; /* Adjust as needed */
height: 60px;
font-size: 30px;
}

.drawing-pad-container {
Expand All @@ -17,23 +17,41 @@ select#font-select option {
position: relative;
margin: 20px 0;
}

.draggable-canvas {
border: 1px solid red;
position: absolute;
touch-action: none;
user-select: none;
top: 0px;
left: 0;
}
.draggable-buttons-box {
position: absolute;
top: 0;
padding: 10px;
width: 100%;
display: flex;
gap: 5px;
justify-content: space-between;
}
.draggable-buttons-box > button {
z-index: 10;

.button-group {
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
padding: 10px;
}

.button-group > button {
background-color: rgba(13, 110, 253, 0.1);
z-index: 10;
align-items: center;
}
.draggable-canvas {
border: 1px solid red;
position: absolute;
touch-action: none;
user-select: none;
top: 0px;
left: 0;
#page-container {
position: relative;
height: 100vh;
}
#pdf-viewer {
height: calc(100% - 100px); /* Adjust according to the size of your banners */
overflow: auto;
}
103 changes: 96 additions & 7 deletions src/main/resources/static/js/draggable-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,20 @@ const DraggableUtils = {
listeners: {
move: (event) => {
const target = event.target;
const x = (parseFloat(target.getAttribute("data-bs-x")) || 0)
+ event.dx;
const y = (parseFloat(target.getAttribute("data-bs-y")) || 0)
+ event.dy;
const x = (parseFloat(target.getAttribute("data-bs-x")) || 0) + event.dx;
const y = (parseFloat(target.getAttribute("data-bs-y")) || 0) + event.dy;

target.style.transform = `translate(${x}px, ${y}px)`;

// Store the position relative to the PDF document
const pdfWidth = DraggableUtils.pdfCanvas.offsetWidth;
const pdfHeight = DraggableUtils.pdfCanvas.offsetHeight;
target.setAttribute("data-bs-x", x);
target.setAttribute("data-bs-y", y);

this.onInteraction(target);
//update the last interacted element
this.lastInteracted = event.target;
DraggableUtils.onInteraction(target);
DraggableUtils.lastInteracted = event.target;
logXValues();
},
},
})
Expand Down Expand Up @@ -156,6 +158,8 @@ const DraggableUtils = {
//Enable Arrow keys directly after the element is created
this.lastInteracted = createdCanvas;

logXValues();

return createdCanvas;
},
createDraggableCanvasFromUrl(dataUrl) {
Expand Down Expand Up @@ -350,7 +354,92 @@ const DraggableUtils = {
this.loadPageContents();
return pdfDocModified;
},

async getOverlayedPdfDocumentZoomed(scale, pdfViewer) {
const pdfBytes = await this.pdfDoc.getData();
const pdfDocModified = await PDFLib.PDFDocument.load(pdfBytes, {
ignoreEncryption: true,
});
this.storePageContents();

const pagesMap = this.documentsMap.get(this.pdfDoc);
for (let pageIdx in pagesMap) {
if (pageIdx.includes("offset")) {
continue;
}

const page = pdfDocModified.getPage(parseInt(pageIdx));
const draggablesData = pagesMap[pageIdx];



for (const draggableData of draggablesData) {
// embed the draggable canvas
const draggableElement = draggableData.element;
console.log(draggableElement.getAttribute("data-bs-x"));
const response = await fetch(draggableElement.toDataURL());
const draggableImgBytes = await response.arrayBuffer();
const pdfImageObject = await pdfDocModified.embedPng(draggableImgBytes);
const draggableCanvases = document.querySelectorAll('[id^="draggable-canvas-"]');
draggableCanvases.forEach(canvas => {
const xValue = canvas.getAttribute('data-bs-x');
console.log(xValue);
});
const pdfDoc = document.getElementById("box-drag-container")
const dragLeft = pdfViewer.scrollLeft / scale
const dragTop = pdfViewer.scrollTop / scale;
const viewportLeft = draggableElement.getAttribute("data-bs-x");
const viewportTop = draggableElement.getAttribute("data-bs-y");
// Log intermediate values for debugging
console.log("scale:", scale);
console.log("viewportLeft:", viewportLeft);
console.log("viewportTop:", viewportTop);
const firstPage = pdfDocModified.getPage(0);

// Calculate the difference in size between pdfDoc and pdfDocModified
const widthDiff = pdfDoc.offsetWidth / firstPage.getWidth();
const heightDiff = pdfDoc.offsetHeight / firstPage.getHeight();

// Draw the image at the position relative to the PDF document
//Distance from edge of viewport to the edge of the pdf + the distance from the edge of the signature to the edge
// of the viewport adjusted to scale.
page.drawImage(pdfImageObject, {
x: ((dragLeft + viewportLeft / scale) / widthDiff),
y: (pdfDoc.offsetHeight - (dragTop + viewportTop / scale) - draggableData.offsetHeight / scale) / heightDiff,
width: draggableData.offsetWidth / scale,
height: draggableData.offsetHeight / scale,
});
console.log("x (final):", dragLeft + viewportLeft / scale);
console.log("y (final):", dragTop + viewportTop / scale);
console.log("width ", pdfDoc.offsetWidth)
console.log("height ", pdfDoc.offsetHeight)
}
}

this.loadPageContents();
const firstPage = pdfDocModified.getPage(0);

// Get the width and height of the page
const width = firstPage.getWidth();
const height = firstPage.getHeight();

console.log("Width of the first page:", width);
console.log("Height of the first page:", height);
return pdfDocModified;


}



};
function logXValues() {
const draggableCanvases = document.querySelectorAll('[id^="draggable-canvas-"]');
draggableCanvases.forEach(canvas => {
const xValue = canvas.getAttribute('data-bs-x');
console.log(xValue);
});
}

document.addEventListener("DOMContentLoaded", () => {
DraggableUtils.init();
Expand Down
120 changes: 102 additions & 18 deletions src/main/resources/templates/sign.html
Original file line number Diff line number Diff line change
Expand Up @@ -228,25 +228,46 @@

<!-- draggables box -->
<div id="box-drag-container" class="show-on-file-selected">
<canvas id="pdf-canvas"></canvas>
<div id="pdf-viewer" style="margin-top: 50px; margin-bottom: 50px;">
<canvas id="pdf-canvas"></canvas>
</div>
<script src="js/draggable-utils.js"></script>
<div class="draggable-buttons-box ignore-rtl">
<button class="btn btn-outline-secondary" onclick="DraggableUtils.deleteDraggableCanvas(DraggableUtils.getLastInteracted())">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" 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>
</button>
<button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.incrementPage() : DraggableUtils.decrementPage()" 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>
</button>
<button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.decrementPage() : DraggableUtils.incrementPage()">
<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>
</button>
<div class="button-group">
<button class="btn btn-outline-secondary" onclick="DraggableUtils.deleteDraggableCanvas(DraggableUtils.getLastInteracted())">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" 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>
</button>
</div>
<div class="button-group">
<!-- Zoom In Button -->
<button class="btn btn-outline-secondary zoomButton" id="zoomIn">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-zoom-in" viewBox="0 0 16 16">
<path d="M15.5 14l-3.79-3.79a6 6 0 1 0-.7.7l3.79 3.79v.5l.7.71L16 14.5v-.5h-.5zM6 10a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm1-7a.5.5 0 0 1 .5.5v1.5h1.5a.5.5 0 0 1 0 1H7.5v1.5a.5.5 0 0 1-1 0V6H5a.5.5 0 0 1 0-1h1.5V3.5a.5.5 0 0 1 .5-.5z"/>
</svg>
</button>

<!-- Zoom Out Button -->
<button class="btn btn-outline-secondary zoomButton" id="zoomOut">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-zoom-out" viewBox="0 0 16 16">
<path d="M15.5 14l-3.79-3.79a6 6 0 1 0-.7.7l3.79 3.79v.5l.7.71L16 14.5v-.5h-.5zM6 10a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm-2-5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1H4a.5.5 0 0 1-.5-.5z"/>
</svg>
</button>
</div>
<div class="button-group">
<button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.incrementPage() : DraggableUtils.decrementPage()" 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>
</button>
<button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.decrementPage() : DraggableUtils.incrementPage()">
<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>
</button>
</div>
</div>
</div>

Expand All @@ -257,7 +278,10 @@

<script>
document.getElementById("download-pdf").addEventListener('click', async() => {
const modifiedPdf = await DraggableUtils.getOverlayedPdfDocument();
const pdfWidth = DraggableUtils.pdfCanvas.width;
const pdfHeight = DraggableUtils.pdfCanvas.height;
const pdfViewer = document.getElementById('pdf-viewer');
const modifiedPdf = await DraggableUtils.getOverlayedPdfDocumentZoomed(scale, pdfViewer);
const modifiedPdfBytes = await modifiedPdf.save();
const blob = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
const link = document.createElement('a');
Expand All @@ -266,6 +290,66 @@
link.click();
});
</script>
<script>
var pdfContainer = document.getElementById('pdf-canvas');

// Initial scale
var scale = 1;

// Set transform origin
pdfContainer.style.transformOrigin = '0 0';

// Event listener for zoom in button
document.getElementById('zoomIn').addEventListener('mousedown', function() {
zoomInterval = setInterval(function() {
scale += 0.1;
pdfContainer.style.transform = 'scale(' + scale + ')';
adjustScrollPosition();
}, 100); // Zoom in every 100ms
});

document.getElementById('zoomIn').addEventListener('mouseup', function() {
clearInterval(zoomInterval); // Stop zooming in
});

document.getElementById('zoomIn').addEventListener('click', function() {
scale += 0.1;
pdfContainer.style.transform = 'scale(' + scale + ')';
adjustScrollPosition();
});

// Event listener for zoom out button
document.getElementById('zoomOut').addEventListener('mousedown', function() {
zoomInterval = setInterval(function() {
if (scale > 1) { // Don't allow to zoom out more than original size
scale -= 0.1;
pdfContainer.style.transform = 'scale(' + scale + ')';
adjustScrollPosition();
}
}, 100); // Zoom out every 100ms
});

document.getElementById('zoomOut').addEventListener('mouseup', function() {
clearInterval(zoomInterval); // Stop zooming out
});

document.getElementById('zoomOut').addEventListener('click', function() {
if (scale > 1) {
scale -= 0.1;
pdfContainer.style.transform = 'scale(' + scale + ')';
adjustScrollPosition();
}
});

function adjustScrollPosition() {
const viewer = document.getElementById('pdf-viewer');
viewer.scrollLeft = viewer.scrollWidth / 2 - viewer.clientWidth / 2;
viewer.scrollTop = viewer.scrollHeight / 2 - viewer.clientHeight / 2;
}


</script>

</div>
</div>
</div>
Expand Down