Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
ComfyUI
Commits
ef71d2c2
Commit
ef71d2c2
authored
Mar 16, 2023
by
comfyanonymous
Browse files
Merge branch 'dragdrop-image-upload' of
https://github.com/pythongosssss/ComfyUI
into m1
parents
74b0104c
235dce39
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
109 additions
and
33 deletions
+109
-33
web/scripts/app.js
web/scripts/app.js
+53
-8
web/scripts/widgets.js
web/scripts/widgets.js
+56
-25
No files found.
web/scripts/app.js
View file @
ef71d2c2
...
@@ -291,9 +291,47 @@ class ComfyApp {
...
@@ -291,9 +291,47 @@ class ComfyApp {
document
.
addEventListener
(
"
drop
"
,
async
(
event
)
=>
{
document
.
addEventListener
(
"
drop
"
,
async
(
event
)
=>
{
event
.
preventDefault
();
event
.
preventDefault
();
event
.
stopPropagation
();
event
.
stopPropagation
();
const
file
=
event
.
dataTransfer
.
files
[
0
];
await
this
.
handleFile
(
file
);
const
n
=
this
.
dragOverNode
;
this
.
dragOverNode
=
null
;
// Node handles file drop, we dont use the built in onDropFile handler as its buggy
// If you drag multiple files it will call it multiple times with the same file
if
(
n
&&
n
.
onDragDrop
&&
(
await
n
.
onDragDrop
(
event
)))
{
return
;
}
await
this
.
handleFile
(
event
.
dataTransfer
.
files
[
0
]);
});
// Always clear over node on drag leave
this
.
canvasEl
.
addEventListener
(
"
dragleave
"
,
async
()
=>
{
if
(
this
.
dragOverNode
)
{
this
.
dragOverNode
=
null
;
this
.
graph
.
setDirtyCanvas
(
false
,
true
);
}
});
});
// Add handler for dropping onto a specific node
this
.
canvasEl
.
addEventListener
(
"
dragover
"
,
(
e
)
=>
{
this
.
canvas
.
adjustMouseEvent
(
e
);
const
node
=
this
.
graph
.
getNodeOnPos
(
e
.
canvasX
,
e
.
canvasY
);
if
(
node
)
{
if
(
node
.
onDragOver
&&
node
.
onDragOver
(
e
))
{
this
.
dragOverNode
=
node
;
// dragover event is fired very frequently, run this on an animation frame
requestAnimationFrame
(()
=>
{
this
.
graph
.
setDirtyCanvas
(
false
,
true
);
});
return
;
}
}
this
.
dragOverNode
=
null
;
},
false
);
}
}
/**
/**
...
@@ -321,15 +359,22 @@ class ComfyApp {
...
@@ -321,15 +359,22 @@ class ComfyApp {
}
}
/**
/**
* Draws
currently executing node highlight
and progress bar
* Draws
node highlights (executing, drag drop)
and progress bar
*/
*/
#
addDrawNode
Progress
Handler
()
{
#
addDrawNodeHandler
()
{
const
orig
=
LGraphCanvas
.
prototype
.
drawNodeShape
;
const
orig
=
LGraphCanvas
.
prototype
.
drawNodeShape
;
const
self
=
this
;
const
self
=
this
;
LGraphCanvas
.
prototype
.
drawNodeShape
=
function
(
node
,
ctx
,
size
,
fgcolor
,
bgcolor
,
selected
,
mouse_over
)
{
LGraphCanvas
.
prototype
.
drawNodeShape
=
function
(
node
,
ctx
,
size
,
fgcolor
,
bgcolor
,
selected
,
mouse_over
)
{
const
res
=
orig
.
apply
(
this
,
arguments
);
const
res
=
orig
.
apply
(
this
,
arguments
);
if
(
node
.
id
+
""
===
self
.
runningNodeId
)
{
let
color
=
null
;
if
(
node
.
id
===
+
self
.
runningNodeId
)
{
color
=
"
#0f0
"
;
}
else
if
(
self
.
dragOverNode
&&
node
.
id
===
self
.
dragOverNode
.
id
)
{
color
=
"
dodgerblue
"
;
}
if
(
color
)
{
const
shape
=
node
.
_shape
||
node
.
constructor
.
shape
||
LiteGraph
.
ROUND_SHAPE
;
const
shape
=
node
.
_shape
||
node
.
constructor
.
shape
||
LiteGraph
.
ROUND_SHAPE
;
ctx
.
lineWidth
=
1
;
ctx
.
lineWidth
=
1
;
ctx
.
globalAlpha
=
0.8
;
ctx
.
globalAlpha
=
0.8
;
...
@@ -355,7 +400,7 @@ class ComfyApp {
...
@@ -355,7 +400,7 @@ class ComfyApp {
);
);
else
if
(
shape
==
LiteGraph
.
CIRCLE_SHAPE
)
else
if
(
shape
==
LiteGraph
.
CIRCLE_SHAPE
)
ctx
.
arc
(
size
[
0
]
*
0.5
,
size
[
1
]
*
0.5
,
size
[
0
]
*
0.5
+
6
,
0
,
Math
.
PI
*
2
);
ctx
.
arc
(
size
[
0
]
*
0.5
,
size
[
1
]
*
0.5
,
size
[
0
]
*
0.5
+
6
,
0
,
Math
.
PI
*
2
);
ctx
.
strokeStyle
=
"
#0f0
"
;
ctx
.
strokeStyle
=
color
;
ctx
.
stroke
();
ctx
.
stroke
();
ctx
.
strokeStyle
=
fgcolor
;
ctx
.
strokeStyle
=
fgcolor
;
ctx
.
globalAlpha
=
1
;
ctx
.
globalAlpha
=
1
;
...
@@ -435,7 +480,7 @@ class ComfyApp {
...
@@ -435,7 +480,7 @@ class ComfyApp {
await
this
.
#
loadExtensions
();
await
this
.
#
loadExtensions
();
// Create and mount the LiteGraph in the DOM
// Create and mount the LiteGraph in the DOM
const
canvasEl
=
Object
.
assign
(
document
.
createElement
(
"
canvas
"
),
{
id
:
"
graph-canvas
"
});
const
canvasEl
=
(
this
.
canvasEl
=
Object
.
assign
(
document
.
createElement
(
"
canvas
"
),
{
id
:
"
graph-canvas
"
})
)
;
document
.
body
.
prepend
(
canvasEl
);
document
.
body
.
prepend
(
canvasEl
);
this
.
graph
=
new
LGraph
();
this
.
graph
=
new
LGraph
();
...
@@ -476,7 +521,7 @@ class ComfyApp {
...
@@ -476,7 +521,7 @@ class ComfyApp {
// Save current workflow automatically
// Save current workflow automatically
setInterval
(()
=>
localStorage
.
setItem
(
"
workflow
"
,
JSON
.
stringify
(
this
.
graph
.
serialize
())),
1000
);
setInterval
(()
=>
localStorage
.
setItem
(
"
workflow
"
,
JSON
.
stringify
(
this
.
graph
.
serialize
())),
1000
);
this
.
#
addDrawNode
Progress
Handler
();
this
.
#
addDrawNodeHandler
();
this
.
#
addApiUpdateHandlers
();
this
.
#
addApiUpdateHandlers
();
this
.
#
addDropHandler
();
this
.
#
addDropHandler
();
this
.
#
addPasteHandler
();
this
.
#
addPasteHandler
();
...
...
web/scripts/widgets.js
View file @
ef71d2c2
...
@@ -132,7 +132,7 @@ export const ComfyWidgets = {
...
@@ -132,7 +132,7 @@ export const ComfyWidgets = {
function
showImage
(
name
)
{
function
showImage
(
name
)
{
// Position the image somewhere sensible
// Position the image somewhere sensible
if
(
!
node
.
imageOffset
)
{
if
(
!
node
.
imageOffset
)
{
node
.
imageOffset
=
uploadWidget
.
last_y
?
uploadWidget
.
last_y
+
25
:
75
;
node
.
imageOffset
=
uploadWidget
.
last_y
?
uploadWidget
.
last_y
+
25
:
75
;
}
}
...
@@ -162,6 +162,36 @@ export const ComfyWidgets = {
...
@@ -162,6 +162,36 @@ export const ComfyWidgets = {
}
}
});
});
async
function
uploadFile
(
file
,
updateNode
)
{
try
{
// Wrap file in formdata so it includes filename
const
body
=
new
FormData
();
body
.
append
(
"
image
"
,
file
);
const
resp
=
await
fetch
(
"
/upload/image
"
,
{
method
:
"
POST
"
,
body
,
});
if
(
resp
.
status
===
200
)
{
const
data
=
await
resp
.
json
();
// Add the file as an option and update the widget value
if
(
!
imageWidget
.
options
.
values
.
includes
(
data
.
name
))
{
imageWidget
.
options
.
values
.
push
(
data
.
name
);
}
if
(
updateNode
)
{
showImage
(
data
.
name
);
imageWidget
.
value
=
data
.
name
;
}
}
else
{
alert
(
resp
.
status
+
"
-
"
+
resp
.
statusText
);
}
}
catch
(
error
)
{
alert
(
error
);
}
}
const
fileInput
=
document
.
createElement
(
"
input
"
);
const
fileInput
=
document
.
createElement
(
"
input
"
);
Object
.
assign
(
fileInput
,
{
Object
.
assign
(
fileInput
,
{
type
:
"
file
"
,
type
:
"
file
"
,
...
@@ -169,30 +199,7 @@ export const ComfyWidgets = {
...
@@ -169,30 +199,7 @@ export const ComfyWidgets = {
style
:
"
display: none
"
,
style
:
"
display: none
"
,
onchange
:
async
()
=>
{
onchange
:
async
()
=>
{
if
(
fileInput
.
files
.
length
)
{
if
(
fileInput
.
files
.
length
)
{
try
{
await
uploadFile
(
fileInput
.
files
[
0
],
true
);
// Wrap file in formdata so it includes filename
const
body
=
new
FormData
();
body
.
append
(
"
image
"
,
fileInput
.
files
[
0
]);
const
resp
=
await
fetch
(
"
/upload/image
"
,
{
method
:
"
POST
"
,
body
,
});
if
(
resp
.
status
===
200
)
{
const
data
=
await
resp
.
json
();
showImage
(
data
.
name
);
// Add the file as an option and update the widget value
if
(
!
imageWidget
.
options
.
values
.
includes
(
data
.
name
))
{
imageWidget
.
options
.
values
.
push
(
data
.
name
);
}
imageWidget
.
value
=
data
.
name
;
}
else
{
alert
(
resp
.
status
+
"
-
"
+
resp
.
statusText
);
}
}
catch
(
error
)
{
alert
(
error
);
}
}
}
},
},
});
});
...
@@ -204,6 +211,30 @@ export const ComfyWidgets = {
...
@@ -204,6 +211,30 @@ export const ComfyWidgets = {
});
});
uploadWidget
.
serialize
=
false
;
uploadWidget
.
serialize
=
false
;
// Add handler to check if an image is being dragged over our node
node
.
onDragOver
=
function
(
e
)
{
if
(
e
.
dataTransfer
&&
e
.
dataTransfer
.
items
)
{
const
image
=
[...
e
.
dataTransfer
.
items
].
find
((
f
)
=>
f
.
kind
===
"
file
"
&&
f
.
type
.
startsWith
(
"
image/
"
));
return
!!
image
;
}
return
false
;
};
// On drop upload files
node
.
onDragDrop
=
function
(
e
)
{
console
.
log
(
"
onDragDrop called
"
);
let
handled
=
false
;
for
(
const
file
of
e
.
dataTransfer
.
files
)
{
if
(
file
.
type
.
startsWith
(
"
image/
"
))
{
uploadFile
(
file
,
!
handled
);
// Dont await these, any order is fine, only update on first one
handled
=
true
;
}
}
return
handled
;
};
return
{
widget
:
uploadWidget
};
return
{
widget
:
uploadWidget
};
},
},
};
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment