Merge pull request #27 from GeorgLegato/custom_navbar_nextImage

Custom navbar next image
pull/29/head
GeorgLegato 2023-04-11 01:58:54 +02:00 committed by GitHub
commit 7577a4e95b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 137 additions and 58 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 KiB

View File

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

View File

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

View File

@ -11,10 +11,67 @@
<div id="panoramaviewer" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);"></div>
<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
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) {
switch (mode) {
case "cubemap":
@ -24,26 +81,39 @@
panorama: {
type: 'net',
path: startImage
}
},
navbar: navBarCustomButtons,
caption: startImage.replace(/^.*[\\\/]/, ''),
keyboardActions: panoViewerKeyboardActions
}
break
default:
return {
container: document.querySelector('#panoramaviewer'),
panorama: startImage,
adapter: panoAdapter
adapter: panoAdapter,
navbar: navBarCustomButtons,
caption: startImage.replace(/^.*[\\\/]/, ''),
keyboardActions: panoViewerKeyboardActions
}
}
}
function createViewer(opts) {
let panObj = opts ? opts : PanOptionsFor(window.frameElement.getAttribute("panoMode"))
panoviewer = new PhotoSphereViewer.Viewer(panObj)
panoviewer.animate({
yaw: Math.PI * 2,
pitch: '360deg',
zoom: 20,
speed: '3rpm',
})
}
function destroyViewer() {
if (panoviewer) {
panoviewer.destroy()
panoviewer = null
}
if (panoviewer) {
panoviewer.destroy()
panoviewer = null
}
}
/* main */
createViewer();

View File

@ -1,11 +1,17 @@
body {
margin: 0 !important;
}
.panogalviewer-iframe body {
overflow: hidden;
margin: 0 !important;
}
#panoviewer-iframe {
width:100%;
height:100vh;
overflow: hidden;
margin: 0;
}
.panogalviewer-iframe {
@ -13,4 +19,12 @@
flex: auto;
width:100%;
height:100%;
margin: 0;
padding: 0;
}
#PanoramaViewer_ToolBox {
width: auto;
flex: 0 1 auto;
}