Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
automatic1111
GitHub Repository: automatic1111/stable-diffusion-webui
Path: blob/master/javascript/imageviewer.js
3055 views
1
// A full size 'lightbox' preview modal shown when left clicking on gallery previews
2
function closeModal() {
3
gradioApp().getElementById("lightboxModal").style.display = "none";
4
}
5
6
function showModal(event) {
7
const source = event.target || event.srcElement;
8
const modalImage = gradioApp().getElementById("modalImage");
9
const modalToggleLivePreviewBtn = gradioApp().getElementById("modal_toggle_live_preview");
10
modalToggleLivePreviewBtn.innerHTML = opts.js_live_preview_in_modal_lightbox ? "🗇" : "🗆";
11
const lb = gradioApp().getElementById("lightboxModal");
12
modalImage.src = source.src;
13
if (modalImage.style.display === 'none') {
14
lb.style.setProperty('background-image', 'url(' + source.src + ')');
15
}
16
lb.style.display = "flex";
17
lb.focus();
18
19
const tabTxt2Img = gradioApp().getElementById("tab_txt2img");
20
const tabImg2Img = gradioApp().getElementById("tab_img2img");
21
// show the save button in modal only on txt2img or img2img tabs
22
if (tabTxt2Img.style.display != "none" || tabImg2Img.style.display != "none") {
23
gradioApp().getElementById("modal_save").style.display = "inline";
24
} else {
25
gradioApp().getElementById("modal_save").style.display = "none";
26
}
27
event.stopPropagation();
28
}
29
30
function negmod(n, m) {
31
return ((n % m) + m) % m;
32
}
33
34
function updateOnBackgroundChange() {
35
const modalImage = gradioApp().getElementById("modalImage");
36
if (modalImage && modalImage.offsetParent) {
37
let currentButton = selected_gallery_button();
38
let preview = gradioApp().querySelectorAll('.livePreview > img');
39
if (opts.js_live_preview_in_modal_lightbox && preview.length > 0) {
40
// show preview image if available
41
modalImage.src = preview[preview.length - 1].src;
42
} else if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) {
43
modalImage.src = currentButton.children[0].src;
44
if (modalImage.style.display === 'none') {
45
const modal = gradioApp().getElementById("lightboxModal");
46
modal.style.setProperty('background-image', `url(${modalImage.src})`);
47
}
48
}
49
}
50
}
51
52
function modalImageSwitch(offset) {
53
var galleryButtons = all_gallery_buttons();
54
55
if (galleryButtons.length > 1) {
56
var result = selected_gallery_index();
57
58
if (result != -1) {
59
var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)];
60
nextButton.click();
61
const modalImage = gradioApp().getElementById("modalImage");
62
const modal = gradioApp().getElementById("lightboxModal");
63
modalImage.src = nextButton.children[0].src;
64
if (modalImage.style.display === 'none') {
65
modal.style.setProperty('background-image', `url(${modalImage.src})`);
66
}
67
setTimeout(function() {
68
modal.focus();
69
}, 10);
70
}
71
}
72
}
73
74
function saveImage() {
75
const tabTxt2Img = gradioApp().getElementById("tab_txt2img");
76
const tabImg2Img = gradioApp().getElementById("tab_img2img");
77
const saveTxt2Img = "save_txt2img";
78
const saveImg2Img = "save_img2img";
79
if (tabTxt2Img.style.display != "none") {
80
gradioApp().getElementById(saveTxt2Img).click();
81
} else if (tabImg2Img.style.display != "none") {
82
gradioApp().getElementById(saveImg2Img).click();
83
} else {
84
console.error("missing implementation for saving modal of this type");
85
}
86
}
87
88
function modalSaveImage(event) {
89
saveImage();
90
event.stopPropagation();
91
}
92
93
function modalNextImage(event) {
94
modalImageSwitch(1);
95
event.stopPropagation();
96
}
97
98
function modalPrevImage(event) {
99
modalImageSwitch(-1);
100
event.stopPropagation();
101
}
102
103
function modalKeyHandler(event) {
104
switch (event.key) {
105
case "s":
106
saveImage();
107
break;
108
case "ArrowLeft":
109
modalPrevImage(event);
110
break;
111
case "ArrowRight":
112
modalNextImage(event);
113
break;
114
case "Escape":
115
closeModal();
116
break;
117
}
118
}
119
120
function setupImageForLightbox(e) {
121
if (e.dataset.modded) {
122
return;
123
}
124
125
e.dataset.modded = true;
126
e.style.cursor = 'pointer';
127
e.style.userSelect = 'none';
128
129
e.addEventListener('mousedown', function(evt) {
130
if (evt.button == 1) {
131
open(evt.target.src);
132
evt.preventDefault();
133
return;
134
}
135
}, true);
136
137
e.addEventListener('click', function(evt) {
138
if (!opts.js_modal_lightbox || evt.button != 0) return;
139
140
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed);
141
evt.preventDefault();
142
showModal(evt);
143
}, true);
144
145
}
146
147
function modalZoomSet(modalImage, enable) {
148
if (modalImage) modalImage.classList.toggle('modalImageFullscreen', !!enable);
149
}
150
151
function modalZoomToggle(event) {
152
var modalImage = gradioApp().getElementById("modalImage");
153
modalZoomSet(modalImage, !modalImage.classList.contains('modalImageFullscreen'));
154
event.stopPropagation();
155
}
156
157
function modalLivePreviewToggle(event) {
158
const modalToggleLivePreview = gradioApp().getElementById("modal_toggle_live_preview");
159
opts.js_live_preview_in_modal_lightbox = !opts.js_live_preview_in_modal_lightbox;
160
modalToggleLivePreview.innerHTML = opts.js_live_preview_in_modal_lightbox ? "🗇" : "🗆";
161
event.stopPropagation();
162
}
163
164
function modalTileImageToggle(event) {
165
const modalImage = gradioApp().getElementById("modalImage");
166
const modal = gradioApp().getElementById("lightboxModal");
167
const isTiling = modalImage.style.display === 'none';
168
if (isTiling) {
169
modalImage.style.display = 'block';
170
modal.style.setProperty('background-image', 'none');
171
} else {
172
modalImage.style.display = 'none';
173
modal.style.setProperty('background-image', `url(${modalImage.src})`);
174
}
175
176
event.stopPropagation();
177
}
178
179
onAfterUiUpdate(function() {
180
var fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img');
181
if (fullImg_preview != null) {
182
fullImg_preview.forEach(setupImageForLightbox);
183
}
184
updateOnBackgroundChange();
185
});
186
187
document.addEventListener("DOMContentLoaded", function() {
188
//const modalFragment = document.createDocumentFragment();
189
const modal = document.createElement('div');
190
modal.onclick = closeModal;
191
modal.id = "lightboxModal";
192
modal.tabIndex = 0;
193
modal.addEventListener('keydown', modalKeyHandler, true);
194
195
const modalControls = document.createElement('div');
196
modalControls.className = 'modalControls gradio-container';
197
modal.append(modalControls);
198
199
const modalZoom = document.createElement('span');
200
modalZoom.className = 'modalZoom cursor';
201
modalZoom.innerHTML = '⤡';
202
modalZoom.addEventListener('click', modalZoomToggle, true);
203
modalZoom.title = "Toggle zoomed view";
204
modalControls.appendChild(modalZoom);
205
206
const modalTileImage = document.createElement('span');
207
modalTileImage.className = 'modalTileImage cursor';
208
modalTileImage.innerHTML = '⊞';
209
modalTileImage.addEventListener('click', modalTileImageToggle, true);
210
modalTileImage.title = "Preview tiling";
211
modalControls.appendChild(modalTileImage);
212
213
const modalSave = document.createElement("span");
214
modalSave.className = "modalSave cursor";
215
modalSave.id = "modal_save";
216
modalSave.innerHTML = "🖫";
217
modalSave.addEventListener("click", modalSaveImage, true);
218
modalSave.title = "Save Image(s)";
219
modalControls.appendChild(modalSave);
220
221
const modalToggleLivePreview = document.createElement('span');
222
modalToggleLivePreview.className = 'modalToggleLivePreview cursor';
223
modalToggleLivePreview.id = "modal_toggle_live_preview";
224
modalToggleLivePreview.innerHTML = "🗆";
225
modalToggleLivePreview.onclick = modalLivePreviewToggle;
226
modalToggleLivePreview.title = "Toggle live preview";
227
modalControls.appendChild(modalToggleLivePreview);
228
229
const modalClose = document.createElement('span');
230
modalClose.className = 'modalClose cursor';
231
modalClose.innerHTML = '×';
232
modalClose.onclick = closeModal;
233
modalClose.title = "Close image viewer";
234
modalControls.appendChild(modalClose);
235
236
const modalImage = document.createElement('img');
237
modalImage.id = 'modalImage';
238
modalImage.onclick = closeModal;
239
modalImage.tabIndex = 0;
240
modalImage.addEventListener('keydown', modalKeyHandler, true);
241
modal.appendChild(modalImage);
242
243
const modalPrev = document.createElement('a');
244
modalPrev.className = 'modalPrev';
245
modalPrev.innerHTML = '❮';
246
modalPrev.tabIndex = 0;
247
modalPrev.addEventListener('click', modalPrevImage, true);
248
modalPrev.addEventListener('keydown', modalKeyHandler, true);
249
modal.appendChild(modalPrev);
250
251
const modalNext = document.createElement('a');
252
modalNext.className = 'modalNext';
253
modalNext.innerHTML = '❯';
254
modalNext.tabIndex = 0;
255
modalNext.addEventListener('click', modalNextImage, true);
256
modalNext.addEventListener('keydown', modalKeyHandler, true);
257
258
modal.appendChild(modalNext);
259
260
try {
261
gradioApp().appendChild(modal);
262
} catch (e) {
263
gradioApp().body.appendChild(modal);
264
}
265
266
document.body.appendChild(modal);
267
268
});
269
270