Path: blob/master/javascript/imageviewer.js
3055 views
// A full size 'lightbox' preview modal shown when left clicking on gallery previews1function closeModal() {2gradioApp().getElementById("lightboxModal").style.display = "none";3}45function showModal(event) {6const source = event.target || event.srcElement;7const modalImage = gradioApp().getElementById("modalImage");8const modalToggleLivePreviewBtn = gradioApp().getElementById("modal_toggle_live_preview");9modalToggleLivePreviewBtn.innerHTML = opts.js_live_preview_in_modal_lightbox ? "🗇" : "🗆";10const lb = gradioApp().getElementById("lightboxModal");11modalImage.src = source.src;12if (modalImage.style.display === 'none') {13lb.style.setProperty('background-image', 'url(' + source.src + ')');14}15lb.style.display = "flex";16lb.focus();1718const tabTxt2Img = gradioApp().getElementById("tab_txt2img");19const tabImg2Img = gradioApp().getElementById("tab_img2img");20// show the save button in modal only on txt2img or img2img tabs21if (tabTxt2Img.style.display != "none" || tabImg2Img.style.display != "none") {22gradioApp().getElementById("modal_save").style.display = "inline";23} else {24gradioApp().getElementById("modal_save").style.display = "none";25}26event.stopPropagation();27}2829function negmod(n, m) {30return ((n % m) + m) % m;31}3233function updateOnBackgroundChange() {34const modalImage = gradioApp().getElementById("modalImage");35if (modalImage && modalImage.offsetParent) {36let currentButton = selected_gallery_button();37let preview = gradioApp().querySelectorAll('.livePreview > img');38if (opts.js_live_preview_in_modal_lightbox && preview.length > 0) {39// show preview image if available40modalImage.src = preview[preview.length - 1].src;41} else if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) {42modalImage.src = currentButton.children[0].src;43if (modalImage.style.display === 'none') {44const modal = gradioApp().getElementById("lightboxModal");45modal.style.setProperty('background-image', `url(${modalImage.src})`);46}47}48}49}5051function modalImageSwitch(offset) {52var galleryButtons = all_gallery_buttons();5354if (galleryButtons.length > 1) {55var result = selected_gallery_index();5657if (result != -1) {58var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)];59nextButton.click();60const modalImage = gradioApp().getElementById("modalImage");61const modal = gradioApp().getElementById("lightboxModal");62modalImage.src = nextButton.children[0].src;63if (modalImage.style.display === 'none') {64modal.style.setProperty('background-image', `url(${modalImage.src})`);65}66setTimeout(function() {67modal.focus();68}, 10);69}70}71}7273function saveImage() {74const tabTxt2Img = gradioApp().getElementById("tab_txt2img");75const tabImg2Img = gradioApp().getElementById("tab_img2img");76const saveTxt2Img = "save_txt2img";77const saveImg2Img = "save_img2img";78if (tabTxt2Img.style.display != "none") {79gradioApp().getElementById(saveTxt2Img).click();80} else if (tabImg2Img.style.display != "none") {81gradioApp().getElementById(saveImg2Img).click();82} else {83console.error("missing implementation for saving modal of this type");84}85}8687function modalSaveImage(event) {88saveImage();89event.stopPropagation();90}9192function modalNextImage(event) {93modalImageSwitch(1);94event.stopPropagation();95}9697function modalPrevImage(event) {98modalImageSwitch(-1);99event.stopPropagation();100}101102function modalKeyHandler(event) {103switch (event.key) {104case "s":105saveImage();106break;107case "ArrowLeft":108modalPrevImage(event);109break;110case "ArrowRight":111modalNextImage(event);112break;113case "Escape":114closeModal();115break;116}117}118119function setupImageForLightbox(e) {120if (e.dataset.modded) {121return;122}123124e.dataset.modded = true;125e.style.cursor = 'pointer';126e.style.userSelect = 'none';127128e.addEventListener('mousedown', function(evt) {129if (evt.button == 1) {130open(evt.target.src);131evt.preventDefault();132return;133}134}, true);135136e.addEventListener('click', function(evt) {137if (!opts.js_modal_lightbox || evt.button != 0) return;138139modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed);140evt.preventDefault();141showModal(evt);142}, true);143144}145146function modalZoomSet(modalImage, enable) {147if (modalImage) modalImage.classList.toggle('modalImageFullscreen', !!enable);148}149150function modalZoomToggle(event) {151var modalImage = gradioApp().getElementById("modalImage");152modalZoomSet(modalImage, !modalImage.classList.contains('modalImageFullscreen'));153event.stopPropagation();154}155156function modalLivePreviewToggle(event) {157const modalToggleLivePreview = gradioApp().getElementById("modal_toggle_live_preview");158opts.js_live_preview_in_modal_lightbox = !opts.js_live_preview_in_modal_lightbox;159modalToggleLivePreview.innerHTML = opts.js_live_preview_in_modal_lightbox ? "🗇" : "🗆";160event.stopPropagation();161}162163function modalTileImageToggle(event) {164const modalImage = gradioApp().getElementById("modalImage");165const modal = gradioApp().getElementById("lightboxModal");166const isTiling = modalImage.style.display === 'none';167if (isTiling) {168modalImage.style.display = 'block';169modal.style.setProperty('background-image', 'none');170} else {171modalImage.style.display = 'none';172modal.style.setProperty('background-image', `url(${modalImage.src})`);173}174175event.stopPropagation();176}177178onAfterUiUpdate(function() {179var fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img');180if (fullImg_preview != null) {181fullImg_preview.forEach(setupImageForLightbox);182}183updateOnBackgroundChange();184});185186document.addEventListener("DOMContentLoaded", function() {187//const modalFragment = document.createDocumentFragment();188const modal = document.createElement('div');189modal.onclick = closeModal;190modal.id = "lightboxModal";191modal.tabIndex = 0;192modal.addEventListener('keydown', modalKeyHandler, true);193194const modalControls = document.createElement('div');195modalControls.className = 'modalControls gradio-container';196modal.append(modalControls);197198const modalZoom = document.createElement('span');199modalZoom.className = 'modalZoom cursor';200modalZoom.innerHTML = '⤡';201modalZoom.addEventListener('click', modalZoomToggle, true);202modalZoom.title = "Toggle zoomed view";203modalControls.appendChild(modalZoom);204205const modalTileImage = document.createElement('span');206modalTileImage.className = 'modalTileImage cursor';207modalTileImage.innerHTML = '⊞';208modalTileImage.addEventListener('click', modalTileImageToggle, true);209modalTileImage.title = "Preview tiling";210modalControls.appendChild(modalTileImage);211212const modalSave = document.createElement("span");213modalSave.className = "modalSave cursor";214modalSave.id = "modal_save";215modalSave.innerHTML = "🖫";216modalSave.addEventListener("click", modalSaveImage, true);217modalSave.title = "Save Image(s)";218modalControls.appendChild(modalSave);219220const modalToggleLivePreview = document.createElement('span');221modalToggleLivePreview.className = 'modalToggleLivePreview cursor';222modalToggleLivePreview.id = "modal_toggle_live_preview";223modalToggleLivePreview.innerHTML = "🗆";224modalToggleLivePreview.onclick = modalLivePreviewToggle;225modalToggleLivePreview.title = "Toggle live preview";226modalControls.appendChild(modalToggleLivePreview);227228const modalClose = document.createElement('span');229modalClose.className = 'modalClose cursor';230modalClose.innerHTML = '×';231modalClose.onclick = closeModal;232modalClose.title = "Close image viewer";233modalControls.appendChild(modalClose);234235const modalImage = document.createElement('img');236modalImage.id = 'modalImage';237modalImage.onclick = closeModal;238modalImage.tabIndex = 0;239modalImage.addEventListener('keydown', modalKeyHandler, true);240modal.appendChild(modalImage);241242const modalPrev = document.createElement('a');243modalPrev.className = 'modalPrev';244modalPrev.innerHTML = '❮';245modalPrev.tabIndex = 0;246modalPrev.addEventListener('click', modalPrevImage, true);247modalPrev.addEventListener('keydown', modalKeyHandler, true);248modal.appendChild(modalPrev);249250const modalNext = document.createElement('a');251modalNext.className = 'modalNext';252modalNext.innerHTML = '❯';253modalNext.tabIndex = 0;254modalNext.addEventListener('click', modalNextImage, true);255modalNext.addEventListener('keydown', modalKeyHandler, true);256257modal.appendChild(modalNext);258259try {260gradioApp().appendChild(modal);261} catch (e) {262gradioApp().body.appendChild(modal);263}264265document.body.appendChild(modal);266267});268269270