Add node video previews (#2635)

This commit is contained in:
bymyself
2025-02-22 16:37:42 -07:00
committed by GitHub
parent c502b86c31
commit f94831d054
12 changed files with 374 additions and 149 deletions

View File

@@ -9,6 +9,7 @@ import {
import { Vector2 } from '@comfyorg/litegraph'
import { IBaseWidget, IWidget } from '@comfyorg/litegraph/dist/types/widgets'
import { useNodeImage, useNodeVideo } from '@/composables/useNodeImage'
import { st } from '@/i18n'
import { ANIM_PREVIEW_WIDGET, ComfyApp, app } from '@/scripts/app'
import { $el } from '@/scripts/ui'
@@ -20,7 +21,7 @@ import { ComfyNodeDef } from '@/types/apiTypes'
import type { NodeId } from '@/types/comfyWorkflow'
import { normalizeI18nKey } from '@/utils/formatUtil'
import { is_all_same_aspect_ratio } from '@/utils/imageUtil'
import { isImageNode } from '@/utils/litegraphUtil'
import { getImageTop, isImageNode, isVideoNode } from '@/utils/litegraphUtil'
import { useExtensionService } from './extensionService'
@@ -363,26 +364,6 @@ export const useLitegraphService = () => {
* @param {*} node The node to add the draw handler
*/
function addDrawBackgroundHandler(node: typeof LGraphNode) {
function getImageTop(node: LGraphNode) {
let shiftY: number
if (node.imageOffset != null) {
return node.imageOffset
} else if (node.widgets?.length) {
const w = node.widgets[node.widgets.length - 1]
shiftY = w.last_y
if (w.computeSize) {
shiftY += w.computeSize()[1] + 4
} else if (w.computedHeight) {
shiftY += w.computedHeight
} else {
shiftY += LiteGraph.NODE_WIDGET_HEIGHT + 4
}
} else {
return node.computeSize()[1]
}
return shiftY
}
node.prototype.setSizeForImage = function (
this: LGraphNode,
force: boolean
@@ -405,49 +386,24 @@ export const useLitegraphService = () => {
) {
if (this.flags.collapsed) return
let imgURLs: string[] = []
const nodeOutputStore = useNodeOutputStore()
const output = nodeOutputStore.getNodeOutputs(this)
let imagesChanged = nodeOutputStore.isImagesChanged(this)
if (output && imagesChanged) {
this.animatedImages = output.animated?.find(Boolean)
this.images = output.images
imgURLs = nodeOutputStore.getNodeImageUrls(this)
}
const preview = nodeOutputStore.getNodePreviews(this)
if (this.preview !== preview) {
this.preview = preview
imagesChanged = true
if (preview != null) {
imgURLs.push(...preview)
}
}
if (imagesChanged) {
this.imageIndex = null
if (imgURLs.length > 0) {
Promise.all(
imgURLs.flat().map((src) => {
return new Promise<HTMLImageElement | null>((r) => {
const img = new Image()
img.onload = () => r(img)
img.onerror = () => r(null)
img.src = src
})
})
).then((imgs) => {
if (
(!output || this.images === output.images) &&
(!preview || this.preview === preview)
) {
this.imgs = imgs.filter(Boolean)
this.setSizeForImage?.()
app.graph.setDirtyCanvas(true)
}
})
const isNewOutput = output && this.images !== output.images
const isNewPreview = preview && this.preview !== preview
if (isNewPreview) this.preview = preview
if (isNewOutput) this.images = output.images
if (isNewOutput || isNewPreview) {
this.animatedImages = output?.animated?.find(Boolean)
if (this.animatedImages || isVideoNode(this)) {
useNodeVideo(this).showPreview()
} else {
this.imgs = undefined
useNodeImage(this).showPreview()
}
}