mirror of
https://github.com/jags111/efficiency-nodes-comfyui.git
synced 2026-03-22 13:42:13 -03:00
145 lines
4.5 KiB
JavaScript
145 lines
4.5 KiB
JavaScript
import { app } from '../../scripts/app.js'
|
|
import { api } from '../../scripts/api.js'
|
|
|
|
function offsetDOMWidget(
|
|
widget,
|
|
ctx,
|
|
node,
|
|
widgetWidth,
|
|
widgetY,
|
|
height
|
|
) {
|
|
const margin = 10
|
|
const elRect = ctx.canvas.getBoundingClientRect()
|
|
const transform = new DOMMatrix()
|
|
.scaleSelf(
|
|
elRect.width / ctx.canvas.width,
|
|
elRect.height / ctx.canvas.height
|
|
)
|
|
.multiplySelf(ctx.getTransform())
|
|
.translateSelf(0, widgetY + margin)
|
|
|
|
const scale = new DOMMatrix().scaleSelf(transform.a, transform.d)
|
|
Object.assign(widget.inputEl.style, {
|
|
transformOrigin: '0 0',
|
|
transform: scale,
|
|
left: `${transform.e}px`,
|
|
top: `${transform.d + transform.f}px`,
|
|
width: `${widgetWidth}px`,
|
|
height: `${(height || widget.parent?.inputHeight || 32) - margin}px`,
|
|
position: 'absolute',
|
|
background: !node.color ? '' : node.color,
|
|
color: !node.color ? '' : 'white',
|
|
zIndex: 5, //app.graph._nodes.indexOf(node),
|
|
})
|
|
}
|
|
|
|
export const hasWidgets = (node) => {
|
|
if (!node.widgets || !node.widgets?.[Symbol.iterator]) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
export const cleanupNode = (node) => {
|
|
if (!hasWidgets(node)) {
|
|
return
|
|
}
|
|
|
|
for (const w of node.widgets) {
|
|
if (w.canvas) {
|
|
w.canvas.remove()
|
|
}
|
|
if (w.inputEl) {
|
|
w.inputEl.remove()
|
|
}
|
|
// calls the widget remove callback
|
|
w.onRemoved?.()
|
|
}
|
|
}
|
|
|
|
const CreatePreviewElement = (name, val, format) => {
|
|
const [type] = format.split('/')
|
|
const w = {
|
|
name,
|
|
type,
|
|
value: val,
|
|
draw: function (ctx, node, widgetWidth, widgetY, height) {
|
|
const [cw, ch] = this.computeSize(widgetWidth)
|
|
offsetDOMWidget(this, ctx, node, widgetWidth, widgetY, ch)
|
|
},
|
|
computeSize: function (_) {
|
|
const ratio = this.inputRatio || 1
|
|
const width = Math.max(220, this.parent.size[0])
|
|
return [width, (width / ratio + 10)]
|
|
},
|
|
onRemoved: function () {
|
|
if (this.inputEl) {
|
|
this.inputEl.remove()
|
|
}
|
|
},
|
|
}
|
|
|
|
w.inputEl = document.createElement(type === 'video' ? 'video' : 'img')
|
|
w.inputEl.src = w.value
|
|
if (type === 'video') {
|
|
w.inputEl.setAttribute('type', 'video/webm');
|
|
w.inputEl.autoplay = true
|
|
w.inputEl.loop = true
|
|
w.inputEl.controls = false;
|
|
}
|
|
w.inputEl.onload = function () {
|
|
w.inputRatio = w.inputEl.naturalWidth / w.inputEl.naturalHeight
|
|
}
|
|
document.body.appendChild(w.inputEl)
|
|
return w
|
|
}
|
|
|
|
const gif_preview = {
|
|
name: 'efficiency.gif_preview',
|
|
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
|
switch (nodeData.name) {
|
|
case 'KSampler (Efficient)':{
|
|
const onExecuted = nodeType.prototype.onExecuted
|
|
nodeType.prototype.onExecuted = function (message) {
|
|
const prefix = 'ad_gif_preview_'
|
|
const r = onExecuted ? onExecuted.apply(this, message) : undefined
|
|
|
|
if (this.widgets) {
|
|
const pos = this.widgets.findIndex((w) => w.name === `${prefix}_0`)
|
|
if (pos !== -1) {
|
|
for (let i = pos; i < this.widgets.length; i++) {
|
|
this.widgets[i].onRemoved?.()
|
|
}
|
|
this.widgets.length = pos
|
|
}
|
|
if (message?.gifs) {
|
|
message.gifs.forEach((params, i) => {
|
|
const previewUrl = api.apiURL(
|
|
'/view?' + new URLSearchParams(params).toString()
|
|
)
|
|
const w = this.addCustomWidget(
|
|
CreatePreviewElement(`${prefix}_${i}`, previewUrl, params.format || 'image/gif')
|
|
)
|
|
w.parent = this
|
|
})
|
|
}
|
|
const onRemoved = this.onRemoved
|
|
this.onRemoved = () => {
|
|
cleanupNode(this)
|
|
return onRemoved?.()
|
|
}
|
|
}
|
|
if (message?.gifs && message.gifs.length > 0) {
|
|
this.setSize([this.size[0], this.computeSize([this.size[0], this.size[1]])[1]]);
|
|
}
|
|
return r
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
app.registerExtension(gif_preview)
|