| | import { $el } from "/scripts/ui.js"; |
| |
|
| | import { imageDrawerComponentManagerInstance } from "../ImageDrawer/Core/ImageDrawerModule.js"; |
| |
|
| | export class ModalManager { |
| |
|
| | constructor(imageIndex = undefined) { |
| |
|
| | |
| | |
| | |
| | this._imageIndex = imageIndex; |
| |
|
| | |
| | this._scale = 1; |
| | this._translateX = -50; |
| | this._translateY = -50; |
| | this._bIsPanningActive = false; |
| | this._bHasPanned = false; |
| | this._startX = 0; |
| | this._startY = 0; |
| |
|
| | this._modalContainer; |
| | this._modalContent; |
| |
|
| | this.handleKeyDownFunction; |
| | this._bButtonPressed = false; |
| | } |
| |
|
| | createModal(modalContent,) { |
| | if (!modalContent) { return; } |
| |
|
| | this._modalContent = modalContent; |
| |
|
| | this._setModalContentStyle(); |
| |
|
| | |
| | this._getOrCreateModalContainer().appendChild(this._modalContent); |
| |
|
| | this._createModalControlButtons(); |
| |
|
| | this.handleKeyDownFunction = (event) => { this._handleKeyDown(event); }; |
| |
|
| | |
| | document.addEventListener("keydown", this.handleKeyDownFunction); |
| |
|
| | return this._getOrCreateModalContainer(); |
| | } |
| |
|
| | createModalReadyImage(href) { |
| | return $el("img", { |
| | src: href, |
| | style: { |
| | position: 'relative', |
| | width: '99vw', |
| | height: '99vh', |
| | objectFit: 'contain', |
| | display: 'block', |
| | margin: 'auto', |
| | }, |
| | }); |
| | } |
| |
|
| | _setModalContentStyle() { |
| |
|
| | this._modalContent.style.position = 'absolute'; |
| | this._modalContent.style.display = "inline-block"; |
| | this._modalContent.style.left = "50%"; |
| | this._modalContent.style.top = "50%"; |
| | this._modalContent.style.transform = "translate(-50%, -50%)"; |
| | this._modalContent.style.maxWidth = "99%"; |
| | this._modalContent.style.maxHeight = "99%"; |
| | this._modalContent.style.overflow = "hidden"; |
| |
|
| | |
| | this._modalContent.draggable = false; |
| | } |
| |
|
| | _createAndOpenModalContainer() { |
| | this._modalContainer = document.createElement("div"); |
| | this._modalContainer.style.display = "block"; |
| | this._modalContainer.style.position = "fixed"; |
| | this._modalContainer.style.zIndex = "10000"; |
| | this._modalContainer.style.left = "0"; |
| | this._modalContainer.style.top = "0"; |
| | this._modalContainer.style.width = "100%"; |
| | this._modalContainer.style.height = "100%"; |
| | this._modalContainer.style.overflow = "auto"; |
| | this._modalContainer.style.backgroundColor = "rgba(0,0,0,0.7)"; |
| |
|
| | this._modalContainer.addEventListener("wheel", (event) => { event.preventDefault(); this._zoom(event); }); |
| | this._modalContainer.addEventListener("mousedown", (event) => { event.preventDefault(); this._startPan(event); }); |
| | this._modalContainer.addEventListener("mousemove", (event) => { event.preventDefault(); this._pan(event); }); |
| | this._modalContainer.addEventListener("mouseup", (event) => { event.preventDefault(); this._onMouseUp(event); }); |
| | this._modalContainer.addEventListener("mouseleave", (event) => { event.preventDefault(); this._endPan(); }); |
| |
|
| | |
| | this._modalContainer.addEventListener("dragstart", (event) => { event.preventDefault(); }); |
| | this._modalContainer.draggable = false; |
| |
|
| | this._modalContainer.data = this; |
| |
|
| | |
| | document.body.appendChild(this._modalContainer); |
| | } |
| |
|
| | _getOrCreateModalContainer() { |
| | if (!this._modalContainer) { |
| | this._createAndOpenModalContainer(); |
| | } |
| | return this._modalContainer; |
| | } |
| |
|
| | _createModalControlButtons() { |
| |
|
| | const createButton = (text, tooltip, clickFunction) => { |
| | const button = $el("button", { |
| | title: tooltip, |
| | textContent: text, |
| | style: { |
| | background: "none", |
| | border: "none", |
| | padding: "0px", |
| | color: "white", |
| | fontWeight: "bolder", |
| | fontSize: "400%", |
| | cursor: 'pointer', |
| | position: "absolute", |
| | filter: "drop-shadow(13px 0px black)", |
| | }, |
| | onmousedown: () => { |
| | this._bButtonPressed = true; |
| | }, |
| | onclick: clickFunction, |
| | }); |
| | button.classList.add("JNodes-interactive-container"); |
| |
|
| | return button; |
| | } |
| |
|
| | const previousImageButton = createButton("<", "See previous image", () => { this._displayNeighbouringImage(-1); }); |
| | previousImageButton.style.left = "2.5%"; |
| | previousImageButton.style.top = "50%"; |
| | this._getOrCreateModalContainer().appendChild(previousImageButton); |
| |
|
| | const nextImageButton = createButton(">", "See next image", () => { this._displayNeighbouringImage(1); }); |
| | nextImageButton.style.right = "2.5%"; |
| | nextImageButton.style.top = "50%"; |
| | this._getOrCreateModalContainer().appendChild(nextImageButton); |
| |
|
| | |
| | if (this._imageIndex != undefined) { |
| |
|
| | const imageDrawerListInstance = imageDrawerComponentManagerInstance.getComponentByName("ImageDrawerList"); |
| | const currentListChildren = imageDrawerListInstance.getVisibleImageListChildren(); |
| |
|
| | const countWidget = $el("label", { |
| | textContent: `${this._imageIndex + 1}/${currentListChildren.length}`, |
| | style: { |
| | background: "rgba(0,0,0,0.5)", |
| | color: "white", |
| | fontWeight: "bolder", |
| | fontSize: "100%", |
| | fontFamily: "arial", |
| | position: "absolute", |
| | right: "1%", |
| | top: "1%" |
| | } |
| | }); |
| | this._getOrCreateModalContainer().appendChild(countWidget); |
| | } |
| | } |
| |
|
| | |
| | _closeModal() { |
| | if (this._modalContainer && this._modalContainer.parentNode) { |
| | this._modalContainer.parentNode.removeChild(this._modalContainer); |
| | } |
| | document.removeEventListener("keydown", this.handleKeyDownFunction); |
| |
|
| | delete this; |
| | } |
| |
|
| | _handleKeyDown(event) { |
| | if (event.key === "Escape") { |
| | event.preventDefault(); |
| | this._closeModal(); |
| | } else if (event.key === "ArrowLeft") { |
| | event.preventDefault(); |
| | this._displayNeighbouringImage(-1); |
| | } else if (event.key === "ArrowRight") { |
| | event.preventDefault(); |
| | this._displayNeighbouringImage(1); |
| | } |
| | } |
| |
|
| | _zoom(event) { |
| | event.preventDefault(); |
| |
|
| | const zoomSpeed = 0.1; |
| | const delta = event.deltaY; |
| |
|
| | |
| | if (delta > 0) { |
| | this._scale = Math.max(0.1, this._scale - zoomSpeed); |
| | } else { |
| | this._scale = Math.min(5, this._scale + zoomSpeed); |
| | } |
| |
|
| | |
| | this._modalContent.style.transform = `translate(${this._translateX}%, ${this._translateY}%) scale(${this._scale})`; |
| | } |
| |
|
| | _startPan(event) { |
| | this._bIsPanningActive = true; |
| | this._getOrCreateModalContainer().style.cursor = "grabbing"; |
| | this._startX = event.clientX; |
| | this._startY = event.clientY; |
| | } |
| |
|
| | _pan(event) { |
| | if (!this._bIsPanningActive) return; |
| |
|
| | const dx = event.clientX - this._startX; |
| | const dy = event.clientY - this._startY; |
| |
|
| | |
| | this._translateX += (dx / this._getOrCreateModalContainer().clientWidth) * 100; |
| | this._translateY += (dy / this._getOrCreateModalContainer().clientHeight) * 100; |
| |
|
| | |
| | this._startX = event.clientX; |
| | this._startY = event.clientY; |
| |
|
| | |
| | this._modalContent.style.transform = `translate(${this._translateX}%, ${this._translateY}%) scale(${this._scale})`; |
| |
|
| | this._bHasPanned = true; |
| | } |
| |
|
| | _endPan() { |
| | this._bIsPanningActive = false; |
| | this._getOrCreateModalContainer().style.cursor = "grab"; |
| | } |
| |
|
| | _onMouseUp(event) { |
| |
|
| | this._endPan(); |
| |
|
| | if (this._bButtonPressed == true) { |
| |
|
| | this._bButtonPressed = false; |
| | return; |
| | } |
| |
|
| | if (this._bHasPanned) { |
| |
|
| | this._bHasPanned = false; |
| |
|
| | } else if (event.button == 0) { |
| |
|
| | this._closeModal(); |
| |
|
| | } |
| | } |
| |
|
| | _displayNeighbouringImage(offset = 0) { |
| |
|
| | if (this._imageIndex !== undefined) { |
| |
|
| | const imageDrawerListInstance = imageDrawerComponentManagerInstance.getComponentByName("ImageDrawerList"); |
| | const currentListChildren = imageDrawerListInstance.getVisibleImageListChildren(); |
| |
|
| | let newImageIndex = this._imageIndex; |
| | let newImage; |
| |
|
| | |
| | do { |
| | newImageIndex += offset; |
| |
|
| | |
| | newImageIndex = ((newImageIndex % currentListChildren.length) + currentListChildren.length) % currentListChildren.length; |
| |
|
| | newImage = currentListChildren[newImageIndex]; |
| |
|
| | |
| | if (newImageIndex == this._imageIndex) { |
| | break; |
| | } |
| |
|
| | } while (newImage?.bIsVideoFormat); |
| |
|
| | const modalManager = new ModalManager(newImageIndex); |
| | modalManager.createModal(modalManager.createModalReadyImage(newImage.fileInfo.href)); |
| |
|
| | this._closeModal(); |
| | } |
| | } |
| | } |