Working lightbox modal ported from A1111

This commit is contained in:
space-nuko
2023-04-07 14:23:03 -05:00
parent f40e46d0c2
commit 6905c65be5
7 changed files with 387 additions and 42 deletions

View File

@@ -6,15 +6,19 @@
import ComfyUIPane from "./ComfyUIPane.svelte";
import ComfyApp, { type SerializedAppState } from "./ComfyApp";
import widgetState from "$lib/stores/widgetState";
import { ImageViewer } from "$lib/ImageViewer";
import { LGraph, LGraphNode } from "@litegraph-ts/core";
import LightboxModal from "./LightboxModal.svelte";
let app: ComfyApp = undefined;
let imageViewer: ImageViewer;
let uiPane: ComfyUIPane = undefined;
let mainElem: HTMLDivElement;
let containerElem: HTMLDivElement;
let resizeTimeout: typeof Timer = -1;
function refreshView(event) {
function refreshView(event?: Event) {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(app.resizeCanvas.bind(app), 250);
}
@@ -87,9 +91,11 @@
(window as any).app = app;
(window as any).appPane = uiPane;
let wrappers = containerElem.querySelectorAll<HTMLDivNode>(".pane-wrapper")
imageViewer = new ImageViewer(app.rootEl);
let wrappers = containerElem.querySelectorAll<HTMLDivElement>(".pane-wrapper")
for (const wrapper of wrappers) {
const paneNode = wrapper.parentNode; // get the node inside the <Pane/>
const paneNode = wrapper.parentNode as HTMLElement; // get the node inside the <Pane/>
paneNode.ontransitionend = () => {
app.resizeCanvas()
}
@@ -97,38 +103,41 @@
})
</script>
<div id="dropzone" class="dropzone"></div>
<div id="container" bind:this={containerElem}>
<Splitpanes theme="comfy" on:resize={refreshView}>
<Pane>
<Splitpanes theme="comfy" on:resize={refreshView} horizontal="{true}">
<Pane>
<ComfyUIPane bind:this={uiPane} {app} />
</Pane>
<Pane bind:size={graphSize}>
<div class="canvas-wrapper pane-wrapper">
<canvas id="graph-canvas" />
</div>
</Pane>
</Splitpanes>
</Pane>
<Pane bind:size={sidebarSize}>
<div class="sidebar-wrapper pane-wrapper">
Sidebar
</div>
</Pane>
</Splitpanes>
</div>
<div id="bottombar">
<Button variant="primary" on:click={queuePrompt}>
Run
</Button>
<Button variant="secondary" on:click={toggleGraph}>
Toggle Graph
</Button>
<Button variant="secondary" on:click={toggleSidebar}>
Toggle Sidebar
</Button>
<div id="main" bind:this={mainElem}>
<div id="dropzone" class="dropzone"></div>
<div id="container" bind:this={containerElem}>
<Splitpanes theme="comfy" on:resize={refreshView}>
<Pane>
<Splitpanes theme="comfy" on:resize={refreshView} horizontal="{true}">
<Pane>
<ComfyUIPane bind:this={uiPane} {app} />
</Pane>
<Pane bind:size={graphSize}>
<div class="canvas-wrapper pane-wrapper">
<canvas id="graph-canvas" />
</div>
</Pane>
</Splitpanes>
</Pane>
<Pane bind:size={sidebarSize}>
<div class="sidebar-wrapper pane-wrapper">
Sidebar
</div>
</Pane>
</Splitpanes>
</div>
<div id="bottombar">
<Button variant="primary" on:click={queuePrompt}>
Run
</Button>
<Button variant="secondary" on:click={toggleGraph}>
Toggle Graph
</Button>
<Button variant="secondary" on:click={toggleSidebar}>
Toggle Sidebar
</Button>
</div>
<LightboxModal />
</div>
<style lang="scss">

View File

@@ -59,6 +59,7 @@ export type Progress = {
export default class ComfyApp {
api: ComfyAPI;
rootEl: HTMLDivElement | null = null;
canvasEl: HTMLCanvasElement | null = null;
canvasCtx: CanvasRenderingContext2D | null = null;
lGraph: LGraph | null = null;
@@ -81,6 +82,7 @@ export default class ComfyApp {
}
async setup(): Promise<void> {
this.rootEl = document.getElementById("main") as HTMLDivElement;
this.canvasEl = document.getElementById("graph-canvas") as HTMLCanvasElement;
this.lGraph = new LGraph();
this.lCanvas = new ComfyGraphCanvas(this, this.canvasEl, this.lGraph);

View File

@@ -0,0 +1,113 @@
<script lang="ts">
import { ImageViewer } from "$lib/ImageViewer";
function toggleZoom(e: Event) {
ImageViewer.instance.modalZoomToggle(e);
}
function previewTiling(e: Event) {
ImageViewer.instance.modalTileImageToggle(e);
}
function closeModal(e: Event) {
ImageViewer.instance.closeModal();
}
function handleKey(e: KeyboardEvent) {
ImageViewer.instance.modalKeyHandler(e);
}
function prevImage(e: Event) {
ImageViewer.instance.modalPrevImage(e);
}
function nextImage(e: Event) {
ImageViewer.instance.modalNextImage(e);
}
</script>
<div id="lightboxModal" on:keydown={handleKey}>
<div class="modalControls gradio-container" on:keydown={handleKey}>
<span class="modalZoom cursor" title="Toggle zoomed view" on:click={toggleZoom} on:keydown={handleKey}>&#10529;</span>
<span class="modalTileImage cursor" title="Preview tiling" on:click={previewTiling} on:keydown={handleKey}>&#8862;</span>
<span class="modalClose cursor" title="Close image viewer" on:click={closeModal} on:keydown={handleKey}>&times;</span>
</div>
<img id="modalImage" alt="Modal" tabIndex="0" on:keydown={handleKey}>
<a class="modalPrev" href="#" tabIndex="0" on:click={prevImage} on:keydown={handleKey}>&#10094</a>
<a class="modalNext" href="#" tabIndex="0" on:click={nextImage} on:keydown={handleKey}>&#10095</a>
</div>
<style>
#lightboxModal{
display: none;
position: fixed;
z-index: 1001;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(20, 20, 20, 0.95);
flex-direction: column;
}
.modalControls {
display: flex;
gap: 1em;
padding: 1em;
background-color: rgba(0,0,0,0.2);
}
.modalClose {
margin-left: auto;
}
.modalControls span{
color: white;
font-size: 35px;
font-weight: bold;
cursor: pointer;
width: 1em;
}
.modalControls span:hover, .modalControls span:focus{
color: #999;
text-decoration: none;
}
#lightboxModal > img {
display: block;
margin: auto;
width: auto;
}
#lightboxModal > img.modalImageFullscreen{
object-fit: contain;
height: 100%;
}
.modalPrev,
.modalNext {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -50px;
color: white;
font-weight: bold;
font-size: 20px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
.modalNext {
right: 0;
border-radius: 3px 0 0 3px;
}
.modalPrev:hover,
.modalNext:hover {
background-color: rgba(0, 0, 0, 0.8);
}
</style>