added next/pre-buttons to navbar of Photoviewer

pull/27/head
GeorgLegato 2023-04-11 01:39:49 +02:00
parent ada1938fdd
commit 5c5d4e0cbd
3 changed files with 123 additions and 58 deletions

View File

@ -49,10 +49,18 @@ function panorama_here(phtml, mode, buttonId) {
let galviewer = gradioApp().querySelector("#panogalviewer-iframe" + tabContext) let galviewer = gradioApp().querySelector("#panogalviewer-iframe" + tabContext)
let galImage = gradioApp().querySelector(containerName + " div > img") let galImage = gradioApp().querySelector(containerName + " div > img")
const galImagesAll = gradioApp().querySelectorAll(containerName + ' .grid-container button img:not([src*="grid-"][src$=".png"])')
const grids = gradioApp().querySelectorAll(containerName + ' .grid-container button img:is([src*="grid-"][src$=".png"])')
const numGrids = grids ? grids.length : 0
const galImagesAllsrc = []
for (var i = 0; i < galImagesAll.length; i++) {
let p = galImagesAll[i].getAttribute('src')
galImagesAllsrc.push(p);
}
if (galviewer) { if (galviewer) {
// not the tab... openpanorama.frame.contentWindow.postMessage({
galviewer.contentWindow.postMessage({ galviewer.contentWindow.postMessage({
type: "panoramaviewer/destroy" type: "panoramaviewer/destroy"
}) })
@ -65,24 +73,31 @@ function panorama_here(phtml, mode, buttonId) {
/* close mimics to open a none-iframe */ /* close mimics to open a none-iframe */
if (!phtml) return if (!phtml) return
/* TODO, disabled; no suitable layout found to insert Panoviewet, yet. /* if nothing selecte, just display the 1st one, if any */
if (!galImage) { if (!galImage && galImagesAll.length > 0) {
// if no item currently selected, check if there is only one gallery-item, galImagesAll[0].click()
//so take this as it is a unique action setTimeout(() => {
let galitems = gradioApp().querySelectorAll(containerName + " .gallery-item") panorama_here(phtml, mode, buttonId)()
if (1 === galitems.length) { return
// galitems[0].click().then( () => { }, 200);
// gradioApp().querySelector(containerName + " ~ div #sendto_panogallery_button").click() return
// })
galImage = galitems[0].querySelector("img")
}
} }
*/
// select only single viewed gallery image, not the small icons in the overview // select only single viewed gallery image, not the small icons in the overview
if (!galImage) return if (!galImage) return
function getIndex() {
const basename= galImage.src.match(/\/([^\/]+)$/)[1]
for (var i = 0; i < galImagesAll.length; i++) {
if (basename === galImagesAll[i].getAttribute('src').replace(/^.*[\\\/]/, '')) {
return i
}
}
return 0
}
const galImageIndex = getIndex()
let parent = galImage.parentElement let parent = galImage.parentElement
//let parent = gradioApp().querySelector(containerName+" > div") // omg //let parent = gradioApp().querySelector(containerName+" > div") // omg
@ -90,8 +105,9 @@ function panorama_here(phtml, mode, buttonId) {
iframe.src = phtml iframe.src = phtml
iframe.id = "panogalviewer-iframe" + tabContext iframe.id = "panogalviewer-iframe" + tabContext
iframe.classList += "panogalviewer-iframe" iframe.classList += "panogalviewer-iframe"
iframe.setAttribute("panoimage", galImage.src) iframe.setAttribute("panoimage", galImagesAllsrc[galImageIndex])
iframe.setAttribute("panoMode", mode) iframe.setAttribute("panoMode", mode)
iframe.setAttribute("panoGalItems", JSON.stringify(galImagesAllsrc))
parent.appendChild(iframe) parent.appendChild(iframe)
galImageDisp = galImage.style.display galImageDisp = galImage.style.display
galImage.style.display = "none" galImage.style.display = "none"
@ -111,7 +127,7 @@ function panorama_send_video(dataURL, name = "Embed Resource") {
resourceName: name, resourceName: name,
}, },
}); });
} }
function panorama_send_image(dataURL, name = "Embed Resource") { function panorama_send_image(dataURL, name = "Embed Resource") {
@ -155,43 +171,22 @@ function panorama_gototab(tabname = "Panorama Viewer", tabsId = "tabs") {
} }
async function panorama_get_image_from_gallery() { async function panorama_get_image_from_gallery(warnOnNoSelect) {
const curGal = gradioApp().querySelector('#tabs button.selected').innerText // get_uiCurrentTab() const curGal = gradioApp().querySelector('#tabs button.selected').innerText // get_uiCurrentTab()
const buttons = gradioApp().querySelectorAll("#"+curGal+"_gallery .grid-container button") const buttons = gradioApp().querySelectorAll("#" + curGal + '_gallery .grid-container button img:not([src*="grid-"][src$=".png"])') // skip grid-img
const button = gradioApp().querySelector("#"+curGal+"_gallery .grid-container button.selected") let button = gradioApp().querySelector("#" + curGal + "_gallery .grid-container button.selected img")
/* pre Gradio 3.23
var buttons = gradioApp().querySelectorAll(
'[style="display: block;"].tabitem div[id$=_gallery] .gallery-item'
);
var button = gradioApp().querySelector(
'[style="display: block;"].tabitem div[id$=_gallery] .gallery-item.\\!ring-2'
);
*/
if (!button && warnOnNoSelect && buttons.length > 1) {
alert("This action requires you have explicitely selected an image from the gallery")
return null
}
if (!button) button = buttons[0]; if (!button) button = buttons[0];
if (!button) if (!button)
throw new Error("[panorama_viewer] No image available in the gallery"); throw new Error("[panorama_viewer] No image available in the gallery");
/* only use file url, not data url return button.src
const canvas = document.createElement("canvas");
const image = document.createElement("img");
image.src = button.querySelector("img").src;
await image.decode();
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas.toDataURL();
*/
return button.querySelector("img").src
} }
function panorama_send_gallery(name = "Embed Resource") { function panorama_send_gallery(name = "Embed Resource") {
@ -374,9 +369,9 @@ document.addEventListener("DOMContentLoaded", () => {
/* routine based on jerx/github, gpl3 */ /* routine based on jerx/github, gpl3 */
function convertto_cubemap() { function convertto_cubemap() {
panorama_get_image_from_gallery() panorama_get_image_from_gallery(true)
.then((dataURL) => { .then((dataURL) => {
if (!dataURL) return
const canvas = document.createElement('canvas') const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d') const ctx = canvas.getContext('2d')
@ -446,7 +441,7 @@ function convertto_cubemap() {
const stack = error.stack; const stack = error.stack;
const match = stack.match(/file=.*javascript\//) const match = stack.match(/file=.*javascript\//)
if (match) { if (match) {
const scriptPath = window.location.href+match; const scriptPath = window.location.href + match;
const workerPath = new URL('e2c.js', scriptPath).href; const workerPath = new URL('e2c.js', scriptPath).href;
worker = new Worker(workerPath); worker = new Worker(workerPath);
} }

View File

@ -45,7 +45,7 @@ def dropHandleGallery(x):
list = txt2img_gallery_component.value list = txt2img_gallery_component.value
img = data_url_to_image(x) img = data_url_to_image(x)
list.append(img) list.append(img)
return list return gr.update(value=list)
def after_component(component, **kwargs): def after_component(component, **kwargs):

View File

@ -11,10 +11,67 @@
<div id="panoramaviewer" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);"></div> <div id="panoramaviewer" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);"></div>
<script> <script>
const startImage = window.frameElement.getAttribute("panoimage") ? window.frameElement.getAttribute("panoimage") : '../docs/assets/img/startimage.jpg' let startImage = window.frameElement.getAttribute("panoimage") ? window.frameElement.getAttribute("panoimage") : '../docs/assets/img/startimage.jpg'
const panoAdapter = window.frameElement.getAttribute("panoMode") === "cubemap" ? PhotoSphereViewer.CubemapAdapter : PhotoSphereViewer.EquirectangularAdapter const panoAdapter = window.frameElement.getAttribute("panoMode") === "cubemap" ? PhotoSphereViewer.CubemapAdapter : PhotoSphereViewer.EquirectangularAdapter
let panoviewer let panoviewer
document.querySelector("body").style.margin = "0";
const panoViewerKeyboardActions = {
keyboardActions: {
...PhotoSphereViewer.DEFAULTS.keyboardActions,
'h': (viewer) => {
if (viewer.panel.isVisible('help')) {
viewer.panel.hide();
} else {
viewer.panel.show({
id: 'help',
content: 'Help content',
});
}
},
'f': (viewer) => viewer.toggleFullscreen(),
}
}
const navBarCustomButtons = [
{
id: 'pano-previmage',
content: '<span>&#x27E8;</span>',
title: 'Previous image from gallery',
className: 'pano-nav-previmg',
onClick: (viewer) => {
// normalize path
startImage = startImage.replace(/\\/g, "/");
const srcArray = JSON.parse(frameElement.getAttribute("panoGalItems"))
if (srcArray.length === 1) { return }
const currentIndex = srcArray.indexOf(startImage)
var previousIndex = currentIndex - 1
if (previousIndex < 0) {
previousIndex = srcArray.length - 1
}
startImage = srcArray[previousIndex]
viewer.setPanorama(startImage, { caption: startImage.replace(/^.*[\\\/]/, '') })
},
},
{
id: 'pano-nextimage',
content: '<span>&#x27E9;</span>',
title: 'Next image from gallery',
className: 'pano-nav-nextimg',
onClick: (viewer) => {
const srcArray = JSON.parse(frameElement.getAttribute("panoGalItems"))
if (srcArray.length === 1) { return }
const currentIndex = srcArray.indexOf(startImage);
var nextIndex = (currentIndex + 1) % srcArray.length;
startImage = srcArray[nextIndex];
viewer.setPanorama(startImage, { caption: startImage.replace(/^.*[\\\/]/, '') })
},
},
'caption',
'fullscreen'
]
function PanOptionsFor(mode) { function PanOptionsFor(mode) {
switch (mode) { switch (mode) {
case "cubemap": case "cubemap":
@ -24,26 +81,39 @@
panorama: { panorama: {
type: 'net', type: 'net',
path: startImage path: startImage
} },
navbar: navBarCustomButtons,
caption: startImage.replace(/^.*[\\\/]/, ''),
keyboardActions: panoViewerKeyboardActions
} }
break break
default: default:
return { return {
container: document.querySelector('#panoramaviewer'), container: document.querySelector('#panoramaviewer'),
panorama: startImage, panorama: startImage,
adapter: panoAdapter adapter: panoAdapter,
navbar: navBarCustomButtons,
caption: startImage.replace(/^.*[\\\/]/, ''),
keyboardActions: panoViewerKeyboardActions
} }
} }
} }
function createViewer(opts) { function createViewer(opts) {
let panObj = opts ? opts : PanOptionsFor(window.frameElement.getAttribute("panoMode")) let panObj = opts ? opts : PanOptionsFor(window.frameElement.getAttribute("panoMode"))
panoviewer = new PhotoSphereViewer.Viewer(panObj) panoviewer = new PhotoSphereViewer.Viewer(panObj)
panoviewer.animate({
yaw: Math.PI * 2,
pitch: '360deg',
zoom: 20,
speed: '3rpm',
})
} }
function destroyViewer() { function destroyViewer() {
if (panoviewer) { if (panoviewer) {
panoviewer.destroy() panoviewer.destroy()
panoviewer = null panoviewer = null
} }
} }
/* main */ /* main */
createViewer(); createViewer();