diff --git a/src/main/resources/static/css/dragdrop.css b/src/main/resources/static/css/dragdrop.css
new file mode 100644
index 00000000..e05cb32e
--- /dev/null
+++ b/src/main/resources/static/css/dragdrop.css
@@ -0,0 +1,78 @@
+#drag-container {
+ position: fixed;
+ display:flex;
+ inset: 0;
+ pointer-events: none;
+ z-index: 10000;
+ visibility: hidden;
+}
+
+#drag-container:not(:empty) {
+ visibility: visible;
+}
+
+#drag-container .dragged-img {
+ position: fixed;
+ max-width: 200px;
+ max-height: 200px;
+ box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.58);
+ transform-origin: top left;
+}
+
+.drag-manager_dragging {
+ width: 0px;
+ visibility: hidden;
+}
+
+.drag-manager_draghover {
+ width: 375px !important;
+}
+
+.drag-manager_draghover .insert-file-button-container {
+ display: none !important;
+}
+
+.drag-manager_draghover .button-container {
+ visibility: hidden !important;
+}
+
+html[lang-direction=ltr] .drag-manager_draghover img {
+ left: calc(50% + 62.5px) !important;
+}
+
+html[lang-direction=rtl] .drag-manager_draghover img {
+ left: unset;
+}
+
+.drag-manager_dragging-container .hide-on-drag {
+ display: none !important;
+}
+
+.drag-manager_endpoint {
+ width: 80px;
+ height: 100%;
+ background-color: #FFFFFF10;
+ transition: width 0.1s;
+ animation: end-drop-expand .3s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.drag-manager_endpoint svg {
+ width: 50px;
+ height: 50px;
+}
+
+.drag-manager_endpoint.drag-manager_draghover {
+ width: 150px !important;
+}
+
+@keyframes end-drop-expand {
+ from {
+ width: 0;
+ }
+ to {
+ width: 80px;
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/static/css/imageHighlighter.css b/src/main/resources/static/css/imageHighlighter.css
new file mode 100644
index 00000000..231895d6
--- /dev/null
+++ b/src/main/resources/static/css/imageHighlighter.css
@@ -0,0 +1,40 @@
+
+#image-highlighter {
+ position: fixed;
+ display:flex;
+ inset: 0;
+ z-index: 10000;
+ background-color: rgba(0, 0, 0, 0);
+ visibility: hidden;
+ align-items: center;
+ justify-content: center;
+ transition: visbility 0.1s linear, background-color 0.1s linear;
+}
+
+#image-highlighter > * {
+ max-width: 80vw;
+ max-height: 80vh;
+ animation: image-highlight .1s linear;
+ transition: transform .1s linear, opacity .1s linear;
+}
+
+#image-highlighter > *.remove {
+ transform: scale(0.8) !important;
+ opacity: 0 !important;
+}
+
+#image-highlighter:not(:empty) {
+ background-color: rgba(0, 0, 0, 0.37);
+ visibility: visible;
+}
+
+@keyframes image-highlight {
+ from {
+ transform: scale(0.8);
+ opacity: 0;
+ }
+ to {
+ transform: scale(1);
+ opacity: 1;
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/static/css/pdfActions.css b/src/main/resources/static/css/pdfActions.css
new file mode 100644
index 00000000..152e3ebc
--- /dev/null
+++ b/src/main/resources/static/css/pdfActions.css
@@ -0,0 +1,87 @@
+
+.pdf-actions_button-container {
+ z-index: 2;
+ display:flex;
+ opacity: 0;
+ transition: opacity 0.1s linear;
+}
+
+.pdf-actions_container:hover .pdf-actions_button-container {
+ opacity: 1;
+}
+
+.pdf-actions_button-container > * {
+ padding: 0.25rem 0.5rem;
+ margin: 3px;
+ display: block;
+}
+
+.pdf-actions_container svg {
+ width: 16px;
+ height: 16px;
+}
+.pdf-actions_container:nth-child(1) .pdf-actions_move-left-button {
+ display: none;
+}
+.pdf-actions_container:last-child .pdf-actions_move-right-button {
+ display: none;
+}
+
+/* "insert pdf" buttons that appear on the right when hover */
+.pdf-actions_insert-file-button-container {
+ translate: 0 -50%;
+ width: 80px;
+ height: 100%;
+
+ z-index: 1;
+ opacity: 0;
+ transition: opacity 0.2s;
+}
+
+.pdf-actions_insert-file-button-container.left {
+ left: -20px;
+}
+
+.pdf-actions_insert-file-button-container.right {
+ right: -20px;
+}
+
+html[lang-direction=ltr] .pdf-actions_insert-file-button-container.right {
+ display:none;
+}
+
+html[lang-direction=rtl] .pdf-actions_insert-file-button-container.left {
+ display:none;
+}
+
+.pdf-actions_insert-file-button-container.left .pdf-actions_insert-file-button {
+ left: 0;
+ translate: 0 -50%;
+}
+
+.pdf-actions_insert-file-button-container.right .pdf-actions_insert-file-button {
+ right: 0;
+ translate: 0 -50%;
+}
+
+html[lang-direction=ltr] .pdf-actions_container:last-child > .pdf-actions_insert-file-button-container.right {
+ display: block;
+}
+
+
+html[lang-direction=rtl] .pdf-actions_container:last-child > .pdf-actions_insert-file-button-container.left {
+ display: block;
+}
+
+.pdf-actions_insert-file-button-container:hover {
+ opacity: 1;
+ transition: opacity 0.05s;
+}
+.pdf-actions_insert-file-button {
+ position: absolute;
+ top: 50%;
+ right: 50%;
+ translate: 50% -50%;
+ aspect-ratio: 1;
+ border-radius: 100px;
+}
\ No newline at end of file
diff --git a/src/main/resources/static/js/multitool/DragDropManager.js b/src/main/resources/static/js/multitool/DragDropManager.js
index 90354551..93fbbdf1 100644
--- a/src/main/resources/static/js/multitool/DragDropManager.js
+++ b/src/main/resources/static/js/multitool/DragDropManager.js
@@ -2,58 +2,95 @@
class DragDropManager {
dragContainer;
+ wrapper;
+ pageDirection;
movePageTo;
pageDragging;
draggelEl;
draggedImageEl;
hoveredEl;
+ endInsertionElement;
- constructor(id) {
+ constructor(id, wrapperId) {
this.dragContainer = document.getElementById(id);
+ this.pageDirection = document.documentElement.getAttribute("lang-direction");
+ this.wrapper = document.getElementById(wrapperId);
this.pageDragging = false;
this.hoveredEl = undefined;
this.draggelEl = undefined
this.draggedImageEl = undefined;
+ var styleElement = document.createElement('link');
+ styleElement.rel = 'stylesheet';
+ styleElement.href = 'css/dragdrop.css'
+
+ document.head.appendChild(styleElement);
+
+ const div = document.createElement('div');
+ div.classList.add('drag-manager_endpoint');
+ div.innerHTML = ``
+ this.endInsertionElement = div;
+
this.startDraggingPage = this.startDraggingPage.bind(this);
this.onDragEl = this.onDragEl.bind(this);
this.stopDraggingPage = this.stopDraggingPage.bind(this);
+
+ this.adapt(div);
}
- startDraggingPage(div, imageSrc) {
+ startDraggingPage(div,) {
this.pageDragging = true;
this.draggedEl = div;
- div.classList.add('dragging');
+ const img = div.querySelector('img');
+ div.classList.add('drag-manager_dragging');
+ const imageSrc = img.src;
+
const imgEl = document.createElement('img');
imgEl.classList.add('dragged-img');
imgEl.src = imageSrc;
this.draggedImageEl = imgEl;
- this.draggedImageEl.style.left = screenX;
- this.draggedImageEl.style.right = screenY;
+ imgEl.style.left = screenX;
+ imgEl.style.right = screenY;
+ imgEl.style.transform = `rotate(${img.style.rotate === '' ? '0deg' : img.style.rotate}) translate(-50%, -50%)`;
this.dragContainer.appendChild(imgEl);
+
window.addEventListener('mouseup', this.stopDraggingPage)
window.addEventListener('mousemove', this.onDragEl)
+ this.wrapper.classList.add('drag-manager_dragging-container');
+ this.wrapper.appendChild(this.endInsertionElement);
}
onDragEl(mouseEvent) {
const { clientX, clientY } = mouseEvent;
if(this.draggedImageEl) {
this.draggedImageEl.style.left = `${clientX}px`;
- this.draggedImageEl.style.top = `${clientY}px`;
+ this.draggedImageEl.style.top = `${clientY}px`;
}
}
stopDraggingPage() {
window.removeEventListener('mousemove', this.onDragEl);
+ this.wrapper.classList.remove('drag-manager_dragging-container');
+ this.wrapper.removeChild(this.endInsertionElement);
window.removeEventListener('mouseup', this.stopDraggingPage)
this.draggedImageEl = undefined;
this.pageDragging = false;
- this.draggedEl.classList.remove('dragging');
- this.hoveredEl.classList.remove('draghover');
+ this.draggedEl.classList.remove('drag-manager_dragging');
+ this.hoveredEl?.classList.remove('drag-manager_draghover');
this.dragContainer.childNodes.forEach((dragChild) => {
this.dragContainer.removeChild(dragChild);
})
+ if(!this.hoveredEl) {
+ return;
+ }
+ if(this.hoveredEl === this.endInsertionElement) {
+ this.movePageTo(this.draggedEl);
+ return;
+ }
this.movePageTo(this.draggedEl, this.hoveredEl);
}
@@ -64,19 +101,19 @@ class DragDropManager {
adapt(div) {
const onDragStart = () => {
- this.startDraggingPage(div, div.querySelector('img').src);
+ this.startDraggingPage(div);
}
const onMouseEnter = () => {
if (this.pageDragging) {
this.hoveredEl = div;
- div.classList.add('draghover');
+ div.classList.add('drag-manager_draghover');
}
}
const onMouseLeave = () => {
this.hoveredEl = undefined
- div.classList.remove('draghover');
+ div.classList.remove('drag-manager_draghover');
}
div.addEventListener('dragstart', onDragStart);
diff --git a/src/main/resources/static/js/multitool/PdfActionsManager.js b/src/main/resources/static/js/multitool/PdfActionsManager.js
index b716f1d1..4bff39e3 100644
--- a/src/main/resources/static/js/multitool/PdfActionsManager.js
+++ b/src/main/resources/static/js/multitool/PdfActionsManager.js
@@ -5,6 +5,12 @@ class PdfActionsManager {
constructor(id) {
this.pagesContainer = document.getElementById(id);
this.pageDirection = document.documentElement.getAttribute("lang-direction");
+
+ var styleElement = document.createElement('link');
+ styleElement.rel = 'stylesheet';
+ styleElement.href = 'css/pdfActions.css'
+
+ document.head.appendChild(styleElement);
}
getPageContainer(element) {
@@ -70,20 +76,21 @@ class PdfActionsManager {
}
adapt(div) {
+ div.classList.add('pdf-actions_container');
const leftDirection = this.pageDirection === 'rtl' ? 'right' : 'left'
const rightDirection = this.pageDirection === 'rtl' ? 'left' : 'right'
const buttonContainer = document.createElement('div');
- buttonContainer.classList.add("button-container");
+ buttonContainer.classList.add("pdf-actions_button-container", "hide-on-drag");
const moveUp = document.createElement('button');
- moveUp.classList.add("move-left-button","btn", "btn-secondary");
+ moveUp.classList.add("pdf-actions_move-left-button","btn", "btn-secondary");
moveUp.innerHTML = ``;
moveUp.onclick = this.moveUpButtonCallback;
buttonContainer.appendChild(moveUp);
const moveDown = document.createElement('button');
- moveDown.classList.add("move-right-button","btn", "btn-secondary");
+ moveDown.classList.add("pdf-actions_move-right-button","btn", "btn-secondary");
moveDown.innerHTML = ``;
moveDown.onclick = this.moveDownButtonCallback;
buttonContainer.appendChild(moveDown);
@@ -120,12 +127,12 @@ class PdfActionsManager {
const insertFileButtonContainer = document.createElement('div');
insertFileButtonContainer.classList.add(
- "insert-file-button-container",
+ "pdf-actions_insert-file-button-container",
leftDirection,
`align-center-${leftDirection}`);
const insertFileButton = document.createElement('button');
- insertFileButton.classList.add("btn", "btn-primary", "insert-file-button");
+ insertFileButton.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button");
insertFileButton.innerHTML = `