imageviewer.js 7.7 KB
Newer Older
A
AUTOMATIC 已提交
1
// A full size 'lightbox' preview modal shown when left clicking on gallery previews
D
DepFA 已提交
2
function closeModal() {
3
    gradioApp().getElementById("lightboxModal").style.display = "none";
D
DepFA 已提交
4 5
}

6
function showModal(event) {
7 8 9 10 11 12 13 14 15 16
    const source = event.target || event.srcElement;
    const modalImage = gradioApp().getElementById("modalImage")
    const lb = gradioApp().getElementById("lightboxModal")
    modalImage.src = source.src
    if (modalImage.style.display === 'none') {
        lb.style.setProperty('background-image', 'url(' + source.src + ')');
    }
    lb.style.display = "block";
    lb.focus()
    event.stopPropagation()
D
DepFA 已提交
17 18
}

19
function negmod(n, m) {
20
    return ((n % m) + m) % m;
21 22
}

23 24 25 26 27 28 29 30 31 32 33
function updateOnBackgroundChange() {
    const modalImage = gradioApp().getElementById("modalImage")
    if (modalImage && modalImage.offsetParent) {
        let allcurrentButtons = gradioApp().querySelectorAll(".gallery-item.transition-all.\\!ring-2")
        let currentButton = null
        allcurrentButtons.forEach(function(elem) {
            if (elem.parentElement.offsetParent) {
                currentButton = elem;
            }
        })

34
        if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) {
35 36 37 38 39
            modalImage.src = currentButton.children[0].src;
            if (modalImage.style.display === 'none') {
                modal.style.setProperty('background-image', `url(${modalImage.src})`)
            }
        }
40
    }
41 42 43 44 45 46 47 48
}

function modalImageSwitch(offset) {
    var allgalleryButtons = gradioApp().querySelectorAll(".gallery-item.transition-all")
    var galleryButtons = []
    allgalleryButtons.forEach(function(elem) {
        if (elem.parentElement.offsetParent) {
            galleryButtons.push(elem);
49
        }
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
    })

    if (galleryButtons.length > 1) {
        var allcurrentButtons = gradioApp().querySelectorAll(".gallery-item.transition-all.\\!ring-2")
        var currentButton = null
        allcurrentButtons.forEach(function(elem) {
            if (elem.parentElement.offsetParent) {
                currentButton = elem;
            }
        })

        var result = -1
        galleryButtons.forEach(function(v, i) {
            if (v == currentButton) {
                result = i
            }
        })

        if (result != -1) {
            nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)]
            nextButton.click()
            const modalImage = gradioApp().getElementById("modalImage");
            const modal = gradioApp().getElementById("lightboxModal");
            modalImage.src = nextButton.children[0].src;
            if (modalImage.style.display === 'none') {
                modal.style.setProperty('background-image', `url(${modalImage.src})`)
            }
            setTimeout(function() {
                modal.focus()
            }, 10)
80
        }
81
    }
82
}
D
DepFA 已提交
83

84 85 86
function modalNextImage(event) {
    modalImageSwitch(1)
    event.stopPropagation()
D
DepFA 已提交
87 88
}

89 90 91
function modalPrevImage(event) {
    modalImageSwitch(-1)
    event.stopPropagation()
92 93
}

94
function modalKeyHandler(event) {
95 96 97 98 99 100 101
    switch (event.key) {
        case "ArrowLeft":
            modalPrevImage(event)
            break;
        case "ArrowRight":
            modalNextImage(event)
            break;
A
Adam Snodgrass 已提交
102 103 104
        case "Escape":
            closeModal();
            break;
105 106 107
    }
}

108
function showGalleryImage() {
D
typo  
DepFA 已提交
109 110
    setTimeout(function() {
        fullImg_preview = gradioApp().querySelectorAll('img.w-full.object-contain')
111 112

        if (fullImg_preview != null) {
D
typo  
DepFA 已提交
113
            fullImg_preview.forEach(function function_name(e) {
G
guaneec 已提交
114 115 116
                if (e.dataset.modded)
                    return;
                e.dataset.modded = true;
D
typo  
DepFA 已提交
117 118
                if(e && e.parentElement.tagName == 'DIV'){
                    e.style.cursor='pointer'
119
                    e.style.userSelect='none'
D
typo  
DepFA 已提交
120
                    e.addEventListener('click', function (evt) {
121
                        if(!opts.js_modal_lightbox) return;
A
Aidan Holland 已提交
122
                        modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed)
123
                        showModal(evt)
124
                    }, true);
D
typo  
DepFA 已提交
125 126 127 128 129 130 131
                }
            });
        }

    }, 100);
}

132 133
function modalZoomSet(modalImage, enable) {
    if (enable) {
D
DepFA 已提交
134
        modalImage.classList.add('modalImageFullscreen');
135
    } else {
D
DepFA 已提交
136 137
        modalImage.classList.remove('modalImageFullscreen');
    }
138 139
}

140
function modalZoomToggle(event) {
141 142
    modalImage = gradioApp().getElementById("modalImage");
    modalZoomSet(modalImage, !modalImage.classList.contains('modalImageFullscreen'))
D
DepFA 已提交
143 144 145
    event.stopPropagation()
}

146
function modalTileImageToggle(event) {
147 148 149 150 151 152 153 154 155 156 157 158 159 160
    const modalImage = gradioApp().getElementById("modalImage");
    const modal = gradioApp().getElementById("lightboxModal");
    const isTiling = modalImage.style.display === 'none';
    if (isTiling) {
        modalImage.style.display = 'block';
        modal.style.setProperty('background-image', 'none')
    } else {
        modalImage.style.display = 'none';
        modal.style.setProperty('background-image', `url(${modalImage.src})`)
    }

    event.stopPropagation()
}

161 162
function galleryImageHandler(e) {
    if (e && e.parentElement.tagName == 'BUTTON') {
D
typo  
DepFA 已提交
163 164 165 166
        e.onclick = showGalleryImage;
    }
}

167
onUiUpdate(function() {
D
DepFA 已提交
168
    fullImg_preview = gradioApp().querySelectorAll('img.w-full')
169 170
    if (fullImg_preview != null) {
        fullImg_preview.forEach(galleryImageHandler);
D
DepFA 已提交
171
    }
172
    updateOnBackgroundChange();
A
AUTOMATIC 已提交
173
})
174 175

document.addEventListener("DOMContentLoaded", function() {
D
DepFA 已提交
176 177 178
    const modalFragment = document.createDocumentFragment();
    const modal = document.createElement('div')
    modal.onclick = closeModal;
D
DepFA 已提交
179
    modal.id = "lightboxModal";
180
    modal.tabIndex = 0
D
DepFA 已提交
181 182
    modal.addEventListener('keydown', modalKeyHandler, true)

183 184 185
    const modalControls = document.createElement('div')
    modalControls.className = 'modalControls gradio-container';
    modal.append(modalControls);
186

D
DepFA 已提交
187 188 189 190
    const modalZoom = document.createElement('span')
    modalZoom.className = 'modalZoom cursor';
    modalZoom.innerHTML = '⤡'
    modalZoom.addEventListener('click', modalZoomToggle, true)
191
    modalZoom.title = "Toggle zoomed view";
192 193
    modalControls.appendChild(modalZoom)

194 195 196
    const modalTileImage = document.createElement('span')
    modalTileImage.className = 'modalTileImage cursor';
    modalTileImage.innerHTML = '⊞'
197
    modalTileImage.addEventListener('click', modalTileImageToggle, true)
198
    modalTileImage.title = "Preview tiling";
199 200 201 202 203 204
    modalControls.appendChild(modalTileImage)

    const modalClose = document.createElement('span')
    modalClose.className = 'modalClose cursor';
    modalClose.innerHTML = '×'
    modalClose.onclick = closeModal;
205
    modalClose.title = "Close image viewer";
206
    modalControls.appendChild(modalClose)
D
DepFA 已提交
207

D
DepFA 已提交
208 209 210
    const modalImage = document.createElement('img')
    modalImage.id = 'modalImage';
    modalImage.onclick = closeModal;
211
    modalImage.tabIndex = 0
212
    modalImage.addEventListener('keydown', modalKeyHandler, true)
D
DepFA 已提交
213 214
    modal.appendChild(modalImage)

215 216 217
    const modalPrev = document.createElement('a')
    modalPrev.className = 'modalPrev';
    modalPrev.innerHTML = '❮'
218 219
    modalPrev.tabIndex = 0
    modalPrev.addEventListener('click', modalPrevImage, true);
220 221 222 223 224 225
    modalPrev.addEventListener('keydown', modalKeyHandler, true)
    modal.appendChild(modalPrev)

    const modalNext = document.createElement('a')
    modalNext.className = 'modalNext';
    modalNext.innerHTML = '❯'
226 227
    modalNext.tabIndex = 0
    modalNext.addEventListener('click', modalNextImage, true);
228 229 230 231 232
    modalNext.addEventListener('keydown', modalKeyHandler, true)

    modal.appendChild(modalNext)


D
DepFA 已提交
233
    gradioApp().getRootNode().appendChild(modal)
234

D
DepFA 已提交
235
    document.body.appendChild(modalFragment);
236

237
});