File size: 4,121 Bytes
c6535db | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
import {app} from "@/composable/comfyAPI.js";
export const ANIM_PREVIEW_WIDGET = '$$comfy_animation_preview'
export function createImageHost(node) {
const el = $el('div.comfy-img-preview')
let currentImgs
let first = true
function updateSize() {
let w = null
let h = null
if (currentImgs) {
let elH = el.clientHeight
if (first) {
first = false
// On first run, if we are small then grow a bit
if (elH < 190) {
elH = 190
}
el.style.setProperty('--comfy-widget-min-height', elH.toString())
} else {
el.style.setProperty('--comfy-widget-min-height', null)
}
const nw = node.size[0]
;({ cellWidth: w, cellHeight: h } = calculateImageGrid(
currentImgs,
nw - 20,
elH
))
w += 'px'
h += 'px'
el.style.setProperty('--comfy-img-preview-width', w)
el.style.setProperty('--comfy-img-preview-height', h)
}
}
return {
el,
updateImages(imgs) {
if (imgs !== currentImgs) {
if (currentImgs == null) {
requestAnimationFrame(() => {
updateSize()
})
}
el.replaceChildren(...imgs)
currentImgs = imgs
node.onResize(node.size)
node.graph.setDirtyCanvas(true, true)
}
},
getHeight() {
updateSize()
},
onDraw() {
// Element from point uses a hittest find elements so we need to toggle pointer events
el.style.pointerEvents = 'all'
const over = document.elementFromPoint(
app.canvas.mouse[0],
app.canvas.mouse[1]
)
el.style.pointerEvents = 'none'
if (!over) return
// Set the overIndex so Open Image etc work
const idx = currentImgs.indexOf(over)
node.overIndex = idx
}
}
}
/**
* Composable for handling animated image previews in nodes
*/
export function useNodeVideoPreview() {
/**
* Shows animated image preview for a node
* @param node The graph node to show the preview for
*/
function showVideoPreview(node) {
if (!node.video?.length) return
if (!node.widgets) return
const widgetIdx = node.widgets.findIndex(
(w) => w.name === ANIM_PREVIEW_WIDGET
)
if (widgetIdx > -1) {
// Replace content in existing widget
// const widget = node.widgets[widgetIdx] || {options: { host: null}}
// widget.options.host.updateImages(node.imgs)
} 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,
// hideOnZoom: false
// }) || {
// options: { host: null }
// }
// widget.serializeValue = () => undefined
// widget.options.host.updateImages(node.imgs)
}
}
/**
* Removes video image preview from a node
* @param node The graph node to remove the preview from
*/
function removeVideoPreview(node) {
if (!node.widgets) return
const widgetIdx = node.widgets.findIndex(
(w) => w.name === 'video-preview'
)
if (widgetIdx > -1) {
node.widgets[widgetIdx].onRemove?.()
node.widgets.splice(widgetIdx, 1)
}
}
return {
showVideoPreview,
removeVideoPreview
}
}
|