Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce0f199981 | ||
|
|
4e4a71b56d | ||
|
|
5004d2df37 | ||
|
|
d57b36a61a | ||
|
|
a35d3223ea |
@@ -25,4 +25,22 @@
|
||||
user-select: none;
|
||||
top: 0px;
|
||||
left: 0;
|
||||
transform-origin: center center;
|
||||
}
|
||||
.rotate-handle {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: blue;
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
cursor: pointer;
|
||||
}
|
||||
.rotate-button {
|
||||
background-color: rgba(13, 110, 253, 0.1);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
@@ -36,4 +36,22 @@ select#font-select option {
|
||||
user-select: none;
|
||||
top: 0px;
|
||||
left: 0;
|
||||
transform-origin: center center;
|
||||
}
|
||||
.rotate-handle {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: blue;
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
cursor: pointer;
|
||||
}
|
||||
.rotate-button {
|
||||
background-color: rgba(13, 110, 253, 0.1);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ const DraggableUtils = {
|
||||
const y = (parseFloat(target.getAttribute("data-bs-y")) || 0)
|
||||
+ event.dy;
|
||||
|
||||
target.style.transform = `translate(${x}px, ${y}px)`;
|
||||
target.style.transform = `translate(${x}px, ${y}px) rotate(${target.getAttribute("data-rotation") || 0}deg)`;
|
||||
target.setAttribute("data-bs-x", x);
|
||||
target.setAttribute("data-bs-y", y);
|
||||
|
||||
@@ -61,7 +61,7 @@ const DraggableUtils = {
|
||||
x += event.deltaRect.left;
|
||||
y += event.deltaRect.top;
|
||||
|
||||
target.style.transform = "translate(" + x + "px," + y + "px)";
|
||||
target.style.transform = `translate(${x}px, ${y}px) rotate(${target.getAttribute("data-rotation") || 0}deg)`;
|
||||
|
||||
target.setAttribute("data-bs-x", x);
|
||||
target.setAttribute("data-bs-y", y);
|
||||
@@ -78,6 +78,17 @@ const DraggableUtils = {
|
||||
}),
|
||||
],
|
||||
inertia: true,
|
||||
})
|
||||
.gesturable({
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
const target = event.target;
|
||||
const rotation = (parseFloat(target.getAttribute("data-rotation")) || 0) + event.da;
|
||||
target.style.transform = `translate(${parseFloat(target.getAttribute("data-bs-x")) || 0}px, ${parseFloat(target.getAttribute("data-bs-y")) || 0}px) rotate(${rotation}deg)`;
|
||||
target.setAttribute("data-rotation", rotation);
|
||||
this.onInteraction(target);
|
||||
}
|
||||
}
|
||||
});
|
||||
//Arrow key Support for Add-Image and Sign pages
|
||||
if(window.location.pathname.endsWith('sign') || window.location.pathname.endsWith('add-image')) {
|
||||
@@ -120,7 +131,7 @@ const DraggableUtils = {
|
||||
}
|
||||
|
||||
// Update position
|
||||
target.style.transform = `translate(${x}px, ${y}px)`;
|
||||
target.style.transform = `translate(${x}px, ${y}px) rotate(${target.getAttribute("data-rotation") || 0}deg)`;
|
||||
target.setAttribute('data-bs-x', x);
|
||||
target.setAttribute('data-bs-y', y);
|
||||
|
||||
@@ -140,9 +151,10 @@ const DraggableUtils = {
|
||||
|
||||
const x = 0;
|
||||
const y = 20;
|
||||
createdCanvas.style.transform = `translate(${x}px, ${y}px)`;
|
||||
createdCanvas.style.transform = `translate(${x}px, ${y}px) rotate(0deg)`;
|
||||
createdCanvas.setAttribute("data-bs-x", x);
|
||||
createdCanvas.setAttribute("data-bs-y", y);
|
||||
createdCanvas.setAttribute("data-rotation", 0);
|
||||
|
||||
//Click element in order to enable arrow keys
|
||||
createdCanvas.addEventListener('click', () => {
|
||||
@@ -223,6 +235,7 @@ const DraggableUtils = {
|
||||
element: el,
|
||||
offsetWidth: el.offsetWidth,
|
||||
offsetHeight: el.offsetHeight,
|
||||
rotation: el.getAttribute("data-rotation") || 0,
|
||||
};
|
||||
});
|
||||
elements.forEach((el) => this.boxDragContainer.removeChild(el));
|
||||
@@ -242,7 +255,11 @@ const DraggableUtils = {
|
||||
|
||||
const draggablesData = pagesMap[this.pageIndex];
|
||||
if (draggablesData) {
|
||||
draggablesData.forEach((draggableData) => this.boxDragContainer.appendChild(draggableData.element));
|
||||
draggablesData.forEach((draggableData) => {
|
||||
const el = draggableData.element;
|
||||
el.style.transform = `translate(${parseFloat(el.getAttribute("data-bs-x")) || 0}px, ${parseFloat(el.getAttribute("data-bs-y")) || 0}px) rotate(${draggableData.rotation}deg)`;
|
||||
this.boxDragContainer.appendChild(el);
|
||||
});
|
||||
}
|
||||
|
||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
||||
@@ -323,6 +340,7 @@ const DraggableUtils = {
|
||||
y: parseFloat(transformComponents[1]),
|
||||
width: draggableData.offsetWidth,
|
||||
height: draggableData.offsetHeight,
|
||||
rotation: parseFloat(draggableData.rotation),
|
||||
};
|
||||
const draggablePositionRelative = {
|
||||
x: draggablePositionPixels.x / offsetWidth,
|
||||
@@ -335,6 +353,7 @@ const DraggableUtils = {
|
||||
y: draggablePositionRelative.y * page.getHeight(),
|
||||
width: draggablePositionRelative.width * page.getWidth(),
|
||||
height: draggablePositionRelative.height * page.getHeight(),
|
||||
rotation: draggablePositionPixels.rotation,
|
||||
};
|
||||
|
||||
// draw the image
|
||||
@@ -343,6 +362,7 @@ const DraggableUtils = {
|
||||
y: page.getHeight() - draggablePositionPdf.y - draggablePositionPdf.height,
|
||||
width: draggablePositionPdf.width,
|
||||
height: draggablePositionPdf.height,
|
||||
rotate: PDFLib.degrees(draggablePositionPdf.rotation),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -350,6 +370,13 @@ const DraggableUtils = {
|
||||
this.loadPageContents();
|
||||
return pdfDocModified;
|
||||
},
|
||||
|
||||
rotateElement(element, angle) {
|
||||
const currentRotation = parseFloat(element.getAttribute("data-rotation")) || 0;
|
||||
const newRotation = currentRotation + angle;
|
||||
element.style.transform = `translate(${parseFloat(element.getAttribute("data-bs-x")) || 0}px, ${parseFloat(element.getAttribute("data-bs-y")) || 0}px) rotate(${newRotation}deg)`;
|
||||
element.setAttribute("data-rotation", newRotation);
|
||||
},
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
|
||||
@@ -83,7 +83,21 @@
|
||||
</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"/>
|
||||
<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 0-.708z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary" onclick="DraggableUtils.rotateElement(DraggableUtils.getLastInteracted(), -90)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.418A6 6 0 1 1 8 2v1z"/>
|
||||
<path d="M8 1a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0v-4A.5.5 0 0 1 8 1z"/>
|
||||
<path d="M8 4.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary" onclick="DraggableUtils.rotateElement(DraggableUtils.getLastInteracted(), 90)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.418A6 6 0 1 0 8 2v1z"/>
|
||||
<path d="M8 1a.5.5 0 0 0-.5.5v4a.5.5 0 0 0 1 0v-4A.5.5 0 0 0 8 1z"/>
|
||||
<path d="M8 4.5a.5.5 0 0 0-.5-.5h-4a.5.5 0 0 0 0 1h4a.5.5 0 0 0 .5-.5z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -103,6 +117,7 @@
|
||||
link.download = originalFileName + '_addedImage.pdf';
|
||||
link.click();
|
||||
});
|
||||
DraggableUtils.init();
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
@@ -111,4 +126,4 @@
|
||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -247,6 +247,20 @@
|
||||
<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>
|
||||
<button class="btn btn-outline-secondary" onclick="DraggableUtils.rotateLeft()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.418A6 6 0 1 1 8 2v1z"/>
|
||||
<path d="M8 1a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0v-4A.5.5 0 0 1 8 1z"/>
|
||||
<path d="M8 4.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary" onclick="DraggableUtils.rotateRight()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.418A6 6 0 1 0 8 2v1z"/>
|
||||
<path d="M8 1a.5.5 0 0 0-.5.5v4a.5.5 0 0 0 1 0v-4A.5.5 0 0 0 8 1z"/>
|
||||
<path d="M8 4.5a.5.5 0 0 0-.5-.5h-4a.5.5 0 0 0 0 1h4a.5.5 0 0 0 .5-.5z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -265,6 +279,7 @@
|
||||
link.download = originalFileName + '_signed.pdf';
|
||||
link.click();
|
||||
});
|
||||
DraggableUtils.init();
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
@@ -273,4 +288,4 @@
|
||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user