Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] [Help wanted] Sign zoom handles #1479

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
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