mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-08 00:50:05 +00:00
Support Right Click -> Save for animated webp (#6095)
Allow for Right Click -> Save Image to work for the "SaveAnimatedWEBP" node. Fixing this revealed other existing issues: - Attempting to resize the node causes runaway scaling - Right clicking on the image directly causes a browser context menu without a save option. Significant rewriting has been performed to resolve both of these issues. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6095-Support-Right-Click-Save-for-animated-webp-28e6d73d3650818e85a2ec58c38c2aae) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import type { IWidget } from '@/lib/litegraph/src/types/widgets'
|
||||
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
|
||||
import { ANIM_PREVIEW_WIDGET } from '@/scripts/app'
|
||||
import { createImageHost } from '@/scripts/ui/imagePreview'
|
||||
import { fitDimensionsToNodeWidth } from '@/utils/imageUtil'
|
||||
import { isDOMWidget } from '@/scripts/domWidget'
|
||||
|
||||
/**
|
||||
* Composable for handling animated image previews in nodes
|
||||
@@ -20,38 +19,38 @@ export function useNodeAnimatedImage() {
|
||||
(w) => w.name === ANIM_PREVIEW_WIDGET
|
||||
)
|
||||
|
||||
node.imgs[0].classList.value = 'block size-full object-contain'
|
||||
if (widgetIdx > -1) {
|
||||
// Replace content in existing widget
|
||||
const widget = node.widgets[widgetIdx] as IWidget & {
|
||||
options: { host: ReturnType<typeof createImageHost> }
|
||||
}
|
||||
widget.options.host.updateImages(node.imgs)
|
||||
const widget = node.widgets[widgetIdx]
|
||||
if (!isDOMWidget(widget)) return
|
||||
widget.element.replaceChildren(node.imgs[0])
|
||||
} else {
|
||||
// Create new widget
|
||||
const host = createImageHost(node)
|
||||
// @ts-expect-error host is not a standard DOM widget option.
|
||||
const widget = node.addDOMWidget(ANIM_PREVIEW_WIDGET, 'img', host.el, {
|
||||
host,
|
||||
// @ts-expect-error `getHeight` of image host returns void instead of number.
|
||||
getHeight: host.getHeight,
|
||||
onDraw: host.onDraw,
|
||||
const element = document.createElement('div')
|
||||
element.appendChild(node.imgs[0])
|
||||
const widget = node.addDOMWidget(ANIM_PREVIEW_WIDGET, 'img', element, {
|
||||
hideOnZoom: false
|
||||
}) as IWidget & {
|
||||
options: { host: ReturnType<typeof createImageHost> }
|
||||
}
|
||||
})
|
||||
node.overIndex = 0
|
||||
|
||||
// Add event listeners for canvas interactions
|
||||
const { handleWheel, handlePointer, forwardEventToCanvas } =
|
||||
useCanvasInteractions()
|
||||
node.imgs[0].style.pointerEvents = 'none'
|
||||
element.addEventListener('wheel', handleWheel)
|
||||
element.addEventListener('pointermove', handlePointer)
|
||||
element.addEventListener('pointerup', handlePointer)
|
||||
element.addEventListener(
|
||||
'pointerdown',
|
||||
(e) => {
|
||||
return e.button !== 2 ? handlePointer(e) : forwardEventToCanvas(e)
|
||||
},
|
||||
true
|
||||
)
|
||||
|
||||
widget.serialize = false
|
||||
widget.serializeValue = () => undefined
|
||||
widget.options.host.updateImages(node.imgs)
|
||||
widget.computeLayoutSize = () => {
|
||||
const img = widget.options.host.getCurrentImage()
|
||||
if (!img) return { minHeight: 0, minWidth: 0 }
|
||||
|
||||
return fitDimensionsToNodeWidth(
|
||||
img.naturalWidth,
|
||||
img.naturalHeight,
|
||||
node.size?.[0] || 0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||
|
||||
import { app } from '../app'
|
||||
import { $el } from '../ui'
|
||||
|
||||
@@ -48,8 +50,8 @@ export function calculateImageGrid(
|
||||
return { cellWidth, cellHeight, cols, rows, shiftX }
|
||||
}
|
||||
|
||||
// @ts-expect-error fixme ts strict error
|
||||
export function createImageHost(node) {
|
||||
/** @knipIgnoreUnusedButUsedByCustomNodes */
|
||||
export function createImageHost(node: LGraphNode) {
|
||||
const el = $el('div.comfy-img-preview')
|
||||
// @ts-expect-error fixme ts strict error
|
||||
let currentImgs
|
||||
@@ -108,8 +110,8 @@ export function createImageHost(node) {
|
||||
}
|
||||
el.replaceChildren(...imgs)
|
||||
currentImgs = imgs
|
||||
node.onResize(node.size)
|
||||
node.graph.setDirtyCanvas(true, true)
|
||||
node.onResize?.(node.size)
|
||||
node.graph?.setDirtyCanvas(true, true)
|
||||
}
|
||||
},
|
||||
getHeight() {
|
||||
|
||||
Reference in New Issue
Block a user