further refactor js
Turn the div adapters into injectable files so that each PdfContainer can be customized. And the adapters can be used in different PdfContainers as well.
This commit is contained in:
parent
e8a91d2631
commit
9a1510a4f1
6 changed files with 206 additions and 190 deletions
|
@ -8,9 +8,8 @@ class DragDropManager {
|
||||||
draggedImageEl;
|
draggedImageEl;
|
||||||
hoveredEl;
|
hoveredEl;
|
||||||
|
|
||||||
constructor(id, movePageTo) {
|
constructor(id) {
|
||||||
this.dragContainer = document.getElementById(id);
|
this.dragContainer = document.getElementById(id);
|
||||||
this.movePageTo = movePageTo;
|
|
||||||
this.pageDragging = false;
|
this.pageDragging = false;
|
||||||
this.hoveredEl = undefined;
|
this.hoveredEl = undefined;
|
||||||
this.draggelEl = undefined
|
this.draggelEl = undefined
|
||||||
|
@ -19,8 +18,6 @@ class DragDropManager {
|
||||||
this.startDraggingPage = this.startDraggingPage.bind(this);
|
this.startDraggingPage = this.startDraggingPage.bind(this);
|
||||||
this.onDragEl = this.onDragEl.bind(this);
|
this.onDragEl = this.onDragEl.bind(this);
|
||||||
this.stopDraggingPage = this.stopDraggingPage.bind(this);
|
this.stopDraggingPage = this.stopDraggingPage.bind(this);
|
||||||
this.attachDragDropCallbacks = this.attachDragDropCallbacks.bind(this);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startDraggingPage(div, imageSrc) {
|
startDraggingPage(div, imageSrc) {
|
||||||
|
@ -34,9 +31,7 @@ class DragDropManager {
|
||||||
this.draggedImageEl.style.left = screenX;
|
this.draggedImageEl.style.left = screenX;
|
||||||
this.draggedImageEl.style.right = screenY;
|
this.draggedImageEl.style.right = screenY;
|
||||||
this.dragContainer.appendChild(imgEl);
|
this.dragContainer.appendChild(imgEl);
|
||||||
window.addEventListener('mouseup', (e) => {
|
window.addEventListener('mouseup', this.stopDraggingPage)
|
||||||
this.stopDraggingPage();
|
|
||||||
})
|
|
||||||
window.addEventListener('mousemove', this.onDragEl)
|
window.addEventListener('mousemove', this.onDragEl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +46,7 @@ class DragDropManager {
|
||||||
|
|
||||||
stopDraggingPage() {
|
stopDraggingPage() {
|
||||||
window.removeEventListener('mousemove', this.onDragEl);
|
window.removeEventListener('mousemove', this.onDragEl);
|
||||||
|
window.removeEventListener('mouseup', this.stopDraggingPage)
|
||||||
this.draggedImageEl = undefined;
|
this.draggedImageEl = undefined;
|
||||||
this.pageDragging = false;
|
this.pageDragging = false;
|
||||||
this.draggedEl.classList.remove('dragging');
|
this.draggedEl.classList.remove('dragging');
|
||||||
|
@ -61,10 +57,14 @@ class DragDropManager {
|
||||||
this.movePageTo(this.draggedEl, this.hoveredEl);
|
this.movePageTo(this.draggedEl, this.hoveredEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setActions({ movePageTo }) {
|
||||||
|
this.movePageTo = movePageTo;
|
||||||
|
}
|
||||||
|
|
||||||
attachDragDropCallbacks(div, imageSrc) {
|
|
||||||
|
adapt(div) {
|
||||||
const onDragStart = () => {
|
const onDragStart = () => {
|
||||||
this.startDraggingPage(div, imageSrc);
|
this.startDraggingPage(div, div.querySelector('img').src);
|
||||||
}
|
}
|
||||||
|
|
||||||
const onMouseEnter = () => {
|
const onMouseEnter = () => {
|
||||||
|
@ -82,6 +82,8 @@ class DragDropManager {
|
||||||
div.addEventListener('dragstart', onDragStart);
|
div.addEventListener('dragstart', onDragStart);
|
||||||
div.addEventListener('mouseenter', onMouseEnter);
|
div.addEventListener('mouseenter', onMouseEnter);
|
||||||
div.addEventListener('mouseleave', onMouseLeave);
|
div.addEventListener('mouseleave', onMouseLeave);
|
||||||
|
|
||||||
|
return div;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,73 +1,75 @@
|
||||||
class PdfActionsManager {
|
class PdfActionsManager {
|
||||||
callbacks;
|
|
||||||
pageDirection;
|
pageDirection;
|
||||||
constructor(id, { movePageTo, addPdfs, rotateElement }) {
|
pagesContainer;
|
||||||
|
|
||||||
|
constructor(id) {
|
||||||
|
this.pagesContainer = document.getElementById(id);
|
||||||
this.pageDirection = document.documentElement.getAttribute("lang-direction");
|
this.pageDirection = document.documentElement.getAttribute("lang-direction");
|
||||||
const moveUpButtonCallback = e => {
|
|
||||||
var imgContainer = e.target;
|
|
||||||
while (!imgContainer.classList.contains(id)) {
|
|
||||||
imgContainer = imgContainer.parentNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPageContainer(element) {
|
||||||
|
var container = element
|
||||||
|
while (!container.classList.contains('page-container')) {
|
||||||
|
container = container.parentNode;
|
||||||
|
}
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
moveUpButtonCallback(e) {
|
||||||
|
var imgContainer = this.getPageContainer(e.target);
|
||||||
|
|
||||||
const sibling = imgContainer.previousSibling;
|
const sibling = imgContainer.previousSibling;
|
||||||
if (sibling) {
|
if (sibling) {
|
||||||
movePageTo(imgContainer, sibling, true);
|
this.movePageTo(imgContainer, sibling, true);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
const moveDownButtonCallback = e => {
|
|
||||||
var imgContainer = e.target;
|
|
||||||
while (!imgContainer.classList.contains(id)) {
|
|
||||||
imgContainer = imgContainer.parentNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveDownButtonCallback(e) {
|
||||||
|
var imgContainer = this.getPageContainer(e.target);
|
||||||
const sibling = imgContainer.nextSibling;
|
const sibling = imgContainer.nextSibling;
|
||||||
if (sibling) {
|
if (sibling) {
|
||||||
movePageTo(imgContainer, sibling.nextSibling, true);
|
this.movePageTo(imgContainer, sibling.nextSibling, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const rotateCCWButtonCallback = e => {
|
|
||||||
var imgContainer = e.target;
|
rotateCCWButtonCallback(e) {
|
||||||
while (!imgContainer.classList.contains(id)) {
|
var imgContainer = this.getPageContainer(e.target);
|
||||||
imgContainer = imgContainer.parentNode;
|
|
||||||
}
|
|
||||||
const img = imgContainer.querySelector("img");
|
const img = imgContainer.querySelector("img");
|
||||||
|
|
||||||
rotateElement(img, -90)
|
this.rotateElement(img, -90)
|
||||||
};
|
};
|
||||||
const rotateCWButtonCallback = e => {
|
|
||||||
var imgContainer = e.target;
|
rotateCWButtonCallback(e) {
|
||||||
while (!imgContainer.classList.contains(id)) {
|
var imgContainer = this.getPageContainer(e.target);
|
||||||
imgContainer = imgContainer.parentNode;
|
|
||||||
}
|
|
||||||
const img = imgContainer.querySelector("img");
|
const img = imgContainer.querySelector("img");
|
||||||
|
|
||||||
rotateElement(img, 90)
|
this.rotateElement(img, 90)
|
||||||
};
|
|
||||||
const deletePageButtonCallback = e => {
|
|
||||||
var imgContainer = e.target;
|
|
||||||
while (!imgContainer.classList.contains(id)) {
|
|
||||||
imgContainer = imgContainer.parentNode;
|
|
||||||
}
|
|
||||||
pagesContainer.removeChild(imgContainer);
|
|
||||||
};
|
|
||||||
const insertFileButtonCallback = e => {
|
|
||||||
var imgContainer = e.target;
|
|
||||||
while (!imgContainer.classList.contains(id)) {
|
|
||||||
imgContainer = imgContainer.parentNode;
|
|
||||||
}
|
|
||||||
addPdfs(imgContainer)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.callbacks = {
|
deletePageButtonCallback(e) {
|
||||||
moveUpButtonCallback,
|
var imgContainer = this.getPageContainer(e.target);
|
||||||
moveDownButtonCallback,
|
this.pagesContainer.removeChild(imgContainer);
|
||||||
rotateCCWButtonCallback,
|
};
|
||||||
rotateCWButtonCallback,
|
|
||||||
deletePageButtonCallback,
|
insertFileButtonCallback(e) {
|
||||||
insertFileButtonCallback
|
var imgContainer = this.getPageContainer(e.target);
|
||||||
}
|
this.addPdfs(imgContainer)
|
||||||
|
};
|
||||||
|
|
||||||
|
setActions({ movePageTo, addPdfs, rotateElement }) {
|
||||||
|
this.movePageTo = movePageTo;
|
||||||
|
this.addPdfs = addPdfs;
|
||||||
|
this.rotateElement = rotateElement;
|
||||||
|
|
||||||
|
this.moveUpButtonCallback = this.moveUpButtonCallback.bind(this);
|
||||||
|
this.moveDownButtonCallback = this.moveDownButtonCallback.bind(this);
|
||||||
|
this.rotateCCWButtonCallback = this.rotateCCWButtonCallback.bind(this);
|
||||||
|
this.rotateCWButtonCallback = this.rotateCWButtonCallback.bind(this);
|
||||||
|
this.deletePageButtonCallback = this.deletePageButtonCallback.bind(this);
|
||||||
|
this.insertFileButtonCallback = this.insertFileButtonCallback.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
attachPDFActions(div) {
|
adapt(div) {
|
||||||
const leftDirection = this.pageDirection === 'rtl' ? 'right' : 'left'
|
const leftDirection = this.pageDirection === 'rtl' ? 'right' : 'left'
|
||||||
const rightDirection = this.pageDirection === 'rtl' ? 'left' : 'right'
|
const rightDirection = this.pageDirection === 'rtl' ? 'left' : 'right'
|
||||||
const buttonContainer = document.createElement('div');
|
const buttonContainer = document.createElement('div');
|
||||||
|
@ -77,13 +79,13 @@ class PdfActionsManager {
|
||||||
const moveUp = document.createElement('button');
|
const moveUp = document.createElement('button');
|
||||||
moveUp.classList.add("move-left-button","btn", "btn-secondary");
|
moveUp.classList.add("move-left-button","btn", "btn-secondary");
|
||||||
moveUp.innerHTML = `<i class="bi bi-arrow-${leftDirection}-short"></i>`;
|
moveUp.innerHTML = `<i class="bi bi-arrow-${leftDirection}-short"></i>`;
|
||||||
moveUp.onclick = this.callbacks.moveUpButtonCallback;
|
moveUp.onclick = this.moveUpButtonCallback;
|
||||||
buttonContainer.appendChild(moveUp);
|
buttonContainer.appendChild(moveUp);
|
||||||
|
|
||||||
const moveDown = document.createElement('button');
|
const moveDown = document.createElement('button');
|
||||||
moveDown.classList.add("move-right-button","btn", "btn-secondary");
|
moveDown.classList.add("move-right-button","btn", "btn-secondary");
|
||||||
moveDown.innerHTML = `<i class="bi bi-arrow-${rightDirection}-short"></i>`;
|
moveDown.innerHTML = `<i class="bi bi-arrow-${rightDirection}-short"></i>`;
|
||||||
moveDown.onclick = this.callbacks.moveDownButtonCallback;
|
moveDown.onclick = this.moveDownButtonCallback;
|
||||||
buttonContainer.appendChild(moveDown);
|
buttonContainer.appendChild(moveDown);
|
||||||
|
|
||||||
const rotateCCW = document.createElement('button');
|
const rotateCCW = document.createElement('button');
|
||||||
|
@ -92,7 +94,7 @@ class PdfActionsManager {
|
||||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z" />
|
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z" />
|
||||||
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z" />
|
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z" />
|
||||||
</svg>`;
|
</svg>`;
|
||||||
rotateCCW.onclick = this.callbacks.rotateCCWButtonCallback;
|
rotateCCW.onclick = this.rotateCCWButtonCallback;
|
||||||
buttonContainer.appendChild(rotateCCW);
|
buttonContainer.appendChild(rotateCCW);
|
||||||
|
|
||||||
const rotateCW = document.createElement('button');
|
const rotateCW = document.createElement('button');
|
||||||
|
@ -101,7 +103,7 @@ class PdfActionsManager {
|
||||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" />
|
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" />
|
||||||
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z" />
|
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z" />
|
||||||
</svg>`;
|
</svg>`;
|
||||||
rotateCW.onclick = this.callbacks.rotateCWButtonCallback;
|
rotateCW.onclick = this.rotateCWButtonCallback;
|
||||||
buttonContainer.appendChild(rotateCW);
|
buttonContainer.appendChild(rotateCW);
|
||||||
|
|
||||||
const deletePage = document.createElement('button');
|
const deletePage = document.createElement('button');
|
||||||
|
@ -110,7 +112,7 @@ class PdfActionsManager {
|
||||||
<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="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"/>
|
<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>`;
|
||||||
deletePage.onclick = this.callbacks.deletePageButtonCallback;
|
deletePage.onclick = this.deletePageButtonCallback;
|
||||||
buttonContainer.appendChild(deletePage);
|
buttonContainer.appendChild(deletePage);
|
||||||
|
|
||||||
div.appendChild(buttonContainer);
|
div.appendChild(buttonContainer);
|
||||||
|
@ -128,7 +130,7 @@ class PdfActionsManager {
|
||||||
<path d="M8 6.5a.5.5 0 0 1 .5.5v1.5H10a.5.5 0 0 1 0 1H8.5V11a.5.5 0 0 1-1 0V9.5H6a.5.5 0 0 1 0-1h1.5V7a.5.5 0 0 1 .5-.5z"/>
|
<path d="M8 6.5a.5.5 0 0 1 .5.5v1.5H10a.5.5 0 0 1 0 1H8.5V11a.5.5 0 0 1-1 0V9.5H6a.5.5 0 0 1 0-1h1.5V7a.5.5 0 0 1 .5-.5z"/>
|
||||||
<path d="M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z"/>
|
<path d="M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z"/>
|
||||||
</svg>`;
|
</svg>`;
|
||||||
insertFileButton.onclick = this.callbacks.insertFileButtonCallback;
|
insertFileButton.onclick = this.insertFileButtonCallback;
|
||||||
insertFileButtonContainer.appendChild(insertFileButton);
|
insertFileButtonContainer.appendChild(insertFileButton);
|
||||||
|
|
||||||
div.appendChild(insertFileButtonContainer);
|
div.appendChild(insertFileButtonContainer);
|
||||||
|
@ -150,6 +152,8 @@ class PdfActionsManager {
|
||||||
insertFileButtonRightContainer.appendChild(insertFileButtonRight);
|
insertFileButtonRightContainer.appendChild(insertFileButtonRight);
|
||||||
|
|
||||||
div.appendChild(insertFileButtonRightContainer);
|
div.appendChild(insertFileButtonRightContainer);
|
||||||
|
|
||||||
|
return div;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
|
|
||||||
|
|
||||||
const scrollDivHorizontally = (id) => {
|
const scrollDivHorizontally = (id) => {
|
||||||
var scrollDelta = 0; // variable to store the accumulated scroll delta
|
var scrollDelta = 0; // variable to store the accumulated scroll delta
|
||||||
var isScrolling = false; // variable to track if scroll is already in progress
|
var isScrolling = false; // variable to track if scroll is already in progress
|
||||||
const pagesContainerWrapper = document.getElementById(id);
|
const divToScrollHorizontally = document.getElementById(id)
|
||||||
function scrollLoop() {
|
function scrollLoop() {
|
||||||
// Scroll the div horizontally by a fraction of the accumulated scroll delta
|
// Scroll the div horizontally by a fraction of the accumulated scroll delta
|
||||||
pagesContainerWrapper.scrollLeft += scrollDelta * 0.1;
|
divToScrollHorizontally.scrollLeft += scrollDelta * 0.1;
|
||||||
|
|
||||||
// Reduce the accumulated scroll delta by a fraction
|
// Reduce the accumulated scroll delta by a fraction
|
||||||
scrollDelta *= 0.9;
|
scrollDelta *= 0.9;
|
||||||
|
@ -19,7 +17,7 @@ const scrollDivHorizontally = (id) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const divToScrollHorizontally = document.getElementById(id)
|
|
||||||
divToScrollHorizontally.addEventListener("wheel", function(e) {
|
divToScrollHorizontally.addEventListener("wheel", function(e) {
|
||||||
e.preventDefault(); // prevent default mousewheel behavior
|
e.preventDefault(); // prevent default mousewheel behavior
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,39 @@
|
||||||
const getImageHighlighterCallback = (id) => {
|
class ImageHiglighter {
|
||||||
const imageHighlighter = document.getElementById(id);
|
imageHighlighter;
|
||||||
imageHighlighter.onclick = () => {
|
constructor(id) {
|
||||||
imageHighlighter.childNodes.forEach((child) => {
|
this.imageHighlighter = document.getElementById(id);
|
||||||
|
this.imageHighlightCallback = this.imageHighlightCallback.bind(this);
|
||||||
|
this.imageHighlighter.onclick = () => {
|
||||||
|
this.imageHighlighter.childNodes.forEach((child) => {
|
||||||
child.classList.add('remove');
|
child.classList.add('remove');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
imageHighlighter.removeChild(child);
|
this.imageHighlighter.removeChild(child);
|
||||||
}, 100)
|
}, 100)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const imageHighlightCallback = (highlightEvent) => {
|
imageHighlightCallback(highlightEvent) {
|
||||||
var bigImg = document.createElement('img');
|
var bigImg = document.createElement('img');
|
||||||
bigImg.onclick = (imageClickEvent) => {
|
bigImg.onclick = (imageClickEvent) => {
|
||||||
// This prevents the highlighter's onClick from closing the image when clicking on the image
|
// This prevents the highlighter's onClick from closing the image when clicking
|
||||||
// instead of next to it.
|
// on the image instead of next to it.
|
||||||
imageClickEvent.preventDefault();
|
imageClickEvent.preventDefault();
|
||||||
imageClickEvent.stopPropagation();
|
imageClickEvent.stopPropagation();
|
||||||
};
|
};
|
||||||
bigImg.src = highlightEvent.target.src;
|
bigImg.src = highlightEvent.target.src;
|
||||||
imageHighlighter.appendChild(bigImg);
|
this.imageHighlighter.appendChild(bigImg);
|
||||||
};
|
};
|
||||||
|
|
||||||
return imageHighlightCallback
|
setActions() {
|
||||||
|
// not needed in this case
|
||||||
|
}
|
||||||
|
|
||||||
|
adapt(div) {
|
||||||
|
const img = div.querySelector('.page-image');
|
||||||
|
img.addEventListener('click', this.imageHighlightCallback)
|
||||||
|
return div;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getImageHighlighterCallback;
|
export default ImageHiglighter;
|
|
@ -1,23 +1,43 @@
|
||||||
import DragDropManager from "./dragDrop.js";
|
class PdfContainer {
|
||||||
import scrollDivHorizontally from "./horizontalScroll.js";
|
fileName;
|
||||||
import getImageHighlighterCallback from "./imageHighlighter.js";
|
pagesContainer;
|
||||||
import PdfActionsManager from './pdfActions.js';
|
pagesContainerWrapper;
|
||||||
|
pdfAdapters;
|
||||||
|
|
||||||
const createPdfContainer = (id, wrapperId, highlighterId, dragElId) => {
|
constructor(id, wrapperId, pdfAdapters) {
|
||||||
var fileName = null;
|
this.fileName = null;
|
||||||
const pagesContainer = document.getElementById(id);
|
this.pagesContainer = document.getElementById(id)
|
||||||
const pagesContainerWrapper = document.getElementById(wrapperId);
|
this.pagesContainerWrapper = document.getElementById(wrapperId);
|
||||||
|
this.movePageTo = this.movePageTo.bind(this);
|
||||||
|
this.addPdfs = this.addPdfs.bind(this);
|
||||||
|
this.rotateElement = this.rotateElement.bind(this);
|
||||||
|
this.rotateAll = this.rotateAll.bind(this);
|
||||||
|
this.exportPdf = this.exportPdf.bind(this);
|
||||||
|
|
||||||
|
this.pdfAdapters = pdfAdapters;
|
||||||
|
|
||||||
const movePageTo = (startElement, endElement, scrollTo = false) => {
|
this.pdfAdapters.forEach(adapter => {
|
||||||
const childArray = Array.from(pagesContainer.childNodes);
|
adapter.setActions({
|
||||||
|
movePageTo: this.movePageTo,
|
||||||
|
addPdfs: this.addPdfs,
|
||||||
|
rotateElement: this.rotateElement,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
window.addPdfs = this.addPdfs;
|
||||||
|
window.exportPdf = this.exportPdf;
|
||||||
|
window.rotateAll = this.rotateAll;
|
||||||
|
}
|
||||||
|
|
||||||
|
movePageTo(startElement, endElement, scrollTo = false) {
|
||||||
|
const childArray = Array.from(this.pagesContainer.childNodes);
|
||||||
const startIndex = childArray.indexOf(startElement);
|
const startIndex = childArray.indexOf(startElement);
|
||||||
const endIndex = childArray.indexOf(endElement);
|
const endIndex = childArray.indexOf(endElement);
|
||||||
pagesContainer.removeChild(startElement);
|
this.pagesContainer.removeChild(startElement);
|
||||||
if(!endElement) {
|
if(!endElement) {
|
||||||
pagesContainer.append(startElement);
|
this.pagesContainer.append(startElement);
|
||||||
} else {
|
} else {
|
||||||
pagesContainer.insertBefore(startElement, endElement);
|
this.pagesContainer.insertBefore(startElement, endElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scrollTo) {
|
if(scrollTo) {
|
||||||
|
@ -26,13 +46,13 @@ const createPdfContainer = (id, wrapperId, highlighterId, dragElId) => {
|
||||||
? 0-width
|
? 0-width
|
||||||
: width;
|
: width;
|
||||||
|
|
||||||
pagesContainerWrapper.scroll({
|
this.pagesContainerWrapper.scroll({
|
||||||
left: pagesContainerWrapper.scrollLeft + vector,
|
left: this.pagesContainerWrapper.scrollLeft + vector,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPdfs(nextSiblingElement) {
|
addPdfs(nextSiblingElement) {
|
||||||
var input = document.createElement('input');
|
var input = document.createElement('input');
|
||||||
input.type = 'file';
|
input.type = 'file';
|
||||||
input.multiple = true;
|
input.multiple = true;
|
||||||
|
@ -40,9 +60,9 @@ const createPdfContainer = (id, wrapperId, highlighterId, dragElId) => {
|
||||||
|
|
||||||
input.onchange = async(e) => {
|
input.onchange = async(e) => {
|
||||||
const files = e.target.files;
|
const files = e.target.files;
|
||||||
fileName = files[0].name;
|
this.fileName = files[0].name;
|
||||||
for (var i=0; i < files.length; i++) {
|
for (var i=0; i < files.length; i++) {
|
||||||
addPdfFile(files[i], nextSiblingElement);
|
this.addPdfFile(files[i], nextSiblingElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelectorAll(".enable-on-file").forEach(element => {
|
document.querySelectorAll(".enable-on-file").forEach(element => {
|
||||||
|
@ -53,7 +73,7 @@ const createPdfContainer = (id, wrapperId, highlighterId, dragElId) => {
|
||||||
input.click();
|
input.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
function rotateElement(element, deg) {
|
rotateElement(element, deg) {
|
||||||
var lastTransform = element.style.rotate;
|
var lastTransform = element.style.rotate;
|
||||||
if (!lastTransform) {
|
if (!lastTransform) {
|
||||||
lastTransform = "0";
|
lastTransform = "0";
|
||||||
|
@ -64,21 +84,8 @@ const createPdfContainer = (id, wrapperId, highlighterId, dragElId) => {
|
||||||
element.style.rotate = newAngle + "deg";
|
element.style.rotate = newAngle + "deg";
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollDivHorizontally(wrapperId);
|
async addPdfFile(file, nextSiblingElement) {
|
||||||
|
const { renderer, pdfDocument } = await this.loadFile(file);
|
||||||
var imageHighlighterCallback;
|
|
||||||
if (highlighterId) {
|
|
||||||
imageHighlighterCallback = getImageHighlighterCallback(highlighterId);
|
|
||||||
}
|
|
||||||
var dragDropManager;
|
|
||||||
if(dragElId) {
|
|
||||||
dragDropManager = new DragDropManager('drag-container', movePageTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
var pdfActionManager = new PdfActionsManager('page-container', { movePageTo, addPdfs, rotateElement });
|
|
||||||
|
|
||||||
async function addPdfFile(file, nextSiblingElement) {
|
|
||||||
const { renderer, pdfDocument } = await loadFile(file);
|
|
||||||
|
|
||||||
for (var i=0; i < renderer.pageCount; i++) {
|
for (var i=0; i < renderer.pageCount; i++) {
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
|
@ -94,32 +101,25 @@ const createPdfContainer = (id, wrapperId, highlighterId, dragElId) => {
|
||||||
img.doc = pdfDocument;
|
img.doc = pdfDocument;
|
||||||
div.appendChild(img);
|
div.appendChild(img);
|
||||||
|
|
||||||
|
this.pdfAdapters.forEach((adapter) => {
|
||||||
if(dragDropManager) {
|
adapter.adapt?.(div)
|
||||||
dragDropManager.attachDragDropCallbacks(div, imageSrc);
|
})
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Making pages larger when clicking on them
|
|
||||||
*/
|
|
||||||
if(imageHighlighterCallback) {
|
|
||||||
img.addEventListener('click', imageHighlighterCallback)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rendering the various buttons to manipulate and move pdf pages
|
|
||||||
*/
|
|
||||||
pdfActionManager.attachPDFActions(div);
|
|
||||||
|
|
||||||
if (nextSiblingElement) {
|
if (nextSiblingElement) {
|
||||||
pagesContainer.insertBefore(div, nextSiblingElement);
|
this.pagesContainer.insertBefore(div, nextSiblingElement);
|
||||||
} else {
|
} else {
|
||||||
pagesContainer.appendChild(div);
|
this.pagesContainer.appendChild(div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toRenderer(objectUrl) {
|
async loadFile(file) {
|
||||||
|
var objectUrl = URL.createObjectURL(file);
|
||||||
|
var pdfDocument = await this.toPdfLib(objectUrl);
|
||||||
|
var renderer = await this.toRenderer(objectUrl);
|
||||||
|
return { renderer, pdfDocument };
|
||||||
|
}
|
||||||
|
|
||||||
|
async toRenderer(objectUrl) {
|
||||||
const pdf = await pdfjsLib.getDocument(objectUrl).promise;
|
const pdf = await pdfjsLib.getDocument(objectUrl).promise;
|
||||||
return {
|
return {
|
||||||
document: pdf,
|
document: pdf,
|
||||||
|
@ -150,31 +150,26 @@ const createPdfContainer = (id, wrapperId, highlighterId, dragElId) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toPdfLib(objectUrl) {
|
async toPdfLib(objectUrl) {
|
||||||
const existingPdfBytes = await fetch(objectUrl).then(res => res.arrayBuffer());
|
const existingPdfBytes = await fetch(objectUrl).then(res => res.arrayBuffer());
|
||||||
const pdfDoc = await PDFLib.PDFDocument.load(existingPdfBytes);
|
const pdfDoc = await PDFLib.PDFDocument.load(existingPdfBytes);
|
||||||
return pdfDoc;
|
return pdfDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadFile(file) {
|
|
||||||
var objectUrl = URL.createObjectURL(file);
|
|
||||||
var pdfDocument = await toPdfLib(objectUrl);
|
|
||||||
var renderer = await toRenderer(objectUrl);
|
|
||||||
return { renderer, pdfDocument };
|
|
||||||
}
|
|
||||||
|
|
||||||
function rotateAll(deg) {
|
|
||||||
for (var i=0; i<pagesContainer.childNodes.length; i++) {
|
rotateAll(deg) {
|
||||||
const img = pagesContainer.childNodes[i].querySelector("img");
|
for (var i=0; i<this.pagesContainer.childNodes.length; i++) {
|
||||||
|
const img = this.pagesContainer.childNodes[i].querySelector("img");
|
||||||
if (!img) continue;
|
if (!img) continue;
|
||||||
rotateElement(img, deg)
|
this.rotateElement(img, deg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function exportPdf() {
|
async exportPdf() {
|
||||||
const pdfDoc = await PDFLib.PDFDocument.create();
|
const pdfDoc = await PDFLib.PDFDocument.create();
|
||||||
for (var i=0; i<pagesContainer.childNodes.length; i++) {
|
for (var i=0; i<this.pagesContainer.childNodes.length; i++) {
|
||||||
const img = pagesContainer.childNodes[i].querySelector("img");
|
const img = this.pagesContainer.childNodes[i].querySelector("img");
|
||||||
if (!img) continue;
|
if (!img) continue;
|
||||||
const pages = await pdfDoc.copyPages(img.doc, [img.pageIdx])
|
const pages = await pdfDoc.copyPages(img.doc, [img.pageIdx])
|
||||||
const page = pages[0];
|
const page = pages[0];
|
||||||
|
@ -202,16 +197,10 @@ const createPdfContainer = (id, wrapperId, highlighterId, dragElId) => {
|
||||||
// Download the file
|
// Download the file
|
||||||
const downloadLink = document.createElement('a');
|
const downloadLink = document.createElement('a');
|
||||||
downloadLink.href = url;
|
downloadLink.href = url;
|
||||||
downloadLink.download = fileName ? fileName : 'managed.pdf';
|
downloadLink.download = this.fileName ? this.fileName : 'managed.pdf';
|
||||||
downloadLink.click();
|
downloadLink.click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
|
||||||
addPdfs,
|
|
||||||
rotateAll,
|
|
||||||
exportPdf,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default createPdfContainer;
|
export default PdfContainer;
|
||||||
|
|
|
@ -52,7 +52,6 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -61,20 +60,32 @@
|
||||||
<div id="drag-container"></div>
|
<div id="drag-container"></div>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import createPdfContainer from '/js/multitool/pdfContainer.js';
|
import PdfContainer from '/js/multitool/PdfContainer.js';
|
||||||
const {
|
import DragDropManager from "/js/multitool/DragDropManager.js";
|
||||||
addPdfs,
|
import scrollDivHorizontally from "/js/multitool/horizontalScroll.js";
|
||||||
exportPdf,
|
import ImageHighlighter from "/js/multitool/ImageHighlighter.js";
|
||||||
rotateAll,
|
import PdfActionsManager from '/js/multitool/PdfActionsManager.js';
|
||||||
} = createPdfContainer(
|
|
||||||
|
// enables drag and drop
|
||||||
|
const dragDropManager = new DragDropManager('drag-container');
|
||||||
|
// enables image highlight on click
|
||||||
|
const imageHighlighter = new ImageHighlighter('image-highlighter');
|
||||||
|
// enables the default action buttons on each pdf
|
||||||
|
const pdfActionsManager = new PdfActionsManager('pages-container');
|
||||||
|
|
||||||
|
// Scroll the wrapper horizontally
|
||||||
|
scrollDivHorizontally('pages-container-wrapper');
|
||||||
|
|
||||||
|
// Automatically exposes rotateAll, addPdfs and exportPdf to the window for the global buttons.
|
||||||
|
const pdfContainer = new PdfContainer(
|
||||||
'pages-container',
|
'pages-container',
|
||||||
'pages-container-wrapper',
|
'pages-container-wrapper',
|
||||||
'image-highlighter',
|
[
|
||||||
'drag-container'
|
dragDropManager,
|
||||||
);
|
imageHighlighter,
|
||||||
window.addPdfs = addPdfs;
|
pdfActionsManager,
|
||||||
window.exportPdf = exportPdf;
|
]
|
||||||
window.rotateAll = rotateAll;
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
Loading…
Reference in a new issue