diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts
new file mode 100644
index 000000000..e61e3ca01
--- /dev/null
+++ b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts
@@ -0,0 +1,49 @@
+import {
+ comfyExpect as expect,
+ comfyPageFixture as test
+} from '../../../fixtures/ComfyPage'
+
+test.describe('Vue Node Custom Colors', () => {
+ test.beforeEach(async ({ comfyPage }) => {
+ await comfyPage.setSetting('Comfy.UseNewMenu', 'Top')
+ await comfyPage.setSetting('Comfy.Canvas.SelectionToolbox', true)
+ await comfyPage.setSetting('Comfy.VueNodes.Enabled', true)
+ await comfyPage.vueNodes.waitForNodes()
+ })
+
+ test('displays color picker button and allows color selection', async ({
+ comfyPage
+ }) => {
+ const loadCheckpointNode = comfyPage.page.locator('[data-node-id]').filter({
+ hasText: 'Load Checkpoint'
+ })
+ await loadCheckpointNode.getByText('Load Checkpoint').click()
+
+ await comfyPage.page.locator('.selection-toolbox .pi-circle-fill').click()
+ await comfyPage.page
+ .locator('.color-picker-container')
+ .locator('i[data-testid="blue"]')
+ .click()
+
+ await expect(comfyPage.canvas).toHaveScreenshot(
+ 'vue-node-custom-color-blue.png'
+ )
+ })
+
+ test('should load node colors from workflow', async ({ comfyPage }) => {
+ await comfyPage.loadWorkflow('nodes/every_node_color')
+ await expect(comfyPage.canvas).toHaveScreenshot(
+ 'vue-node-custom-colors-dark-all-colors.png'
+ )
+ })
+
+ test('should show brightened node colors on light theme', async ({
+ comfyPage
+ }) => {
+ await comfyPage.setSetting('Comfy.ColorPalette', 'light')
+ await comfyPage.loadWorkflow('nodes/every_node_color')
+ await expect(comfyPage.canvas).toHaveScreenshot(
+ 'vue-node-custom-colors-light-all-colors.png'
+ )
+ })
+})
diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png
new file mode 100644
index 000000000..3f02b8cf6
Binary files /dev/null and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png
new file mode 100644
index 000000000..e3f693e8f
Binary files /dev/null and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png
new file mode 100644
index 000000000..77d7c5fb0
Binary files /dev/null and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png differ
diff --git a/src/composables/graph/useGraphNodeManager.ts b/src/composables/graph/useGraphNodeManager.ts
index beaca8d4c..55b06cabd 100644
--- a/src/composables/graph/useGraphNodeManager.ts
+++ b/src/composables/graph/useGraphNodeManager.ts
@@ -41,6 +41,8 @@ export interface VueNodeData {
collapsed?: boolean
pinned?: boolean
}
+ color?: string
+ bgcolor?: string
}
export interface GraphNodeManager {
@@ -126,7 +128,9 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
widgets: safeWidgets,
inputs: node.inputs ? [...node.inputs] : undefined,
outputs: node.outputs ? [...node.outputs] : undefined,
- flags: node.flags ? { ...node.flags } : undefined
+ flags: node.flags ? { ...node.flags } : undefined,
+ color: node.color || undefined,
+ bgcolor: node.bgcolor || undefined
}
}
@@ -449,6 +453,24 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
...currentData,
mode: typeof event.newValue === 'number' ? event.newValue : 0
})
+ break
+ case 'color':
+ vueNodeData.set(nodeId, {
+ ...currentData,
+ color:
+ typeof event.newValue === 'string'
+ ? event.newValue
+ : undefined
+ })
+ break
+ case 'bgcolor':
+ vueNodeData.set(nodeId, {
+ ...currentData,
+ bgcolor:
+ typeof event.newValue === 'string'
+ ? event.newValue
+ : undefined
+ })
}
}
} else if (
diff --git a/src/lib/litegraph/src/LGraphNodeProperties.ts b/src/lib/litegraph/src/LGraphNodeProperties.ts
index 271d98e1e..f4a5d0c13 100644
--- a/src/lib/litegraph/src/LGraphNodeProperties.ts
+++ b/src/lib/litegraph/src/LGraphNodeProperties.ts
@@ -7,7 +7,9 @@ const DEFAULT_TRACKED_PROPERTIES: string[] = [
'title',
'flags.collapsed',
'flags.pinned',
- 'mode'
+ 'mode',
+ 'color',
+ 'bgcolor'
]
/**
diff --git a/src/renderer/extensions/vueNodes/components/LGraphNode.vue b/src/renderer/extensions/vueNodes/components/LGraphNode.vue
index a86d8de3a..dc03dae00 100644
--- a/src/renderer/extensions/vueNodes/components/LGraphNode.vue
+++ b/src/renderer/extensions/vueNodes/components/LGraphNode.vue
@@ -34,7 +34,9 @@
:style="[
{
transform: `translate(${position.x ?? 0}px, ${(position.y ?? 0) - LiteGraph.NODE_TITLE_HEIGHT}px)`,
- zIndex: zIndex
+ zIndex: zIndex,
+ backgroundColor: nodeBodyBackgroundColor,
+ opacity: nodeOpacity
},
dragStyle
]"
@@ -47,9 +49,14 @@
-
{
const bypassed = computed((): boolean => nodeData.mode === 4)
const muted = computed((): boolean => nodeData.mode === 2) // NEVER mode
+const nodeBodyBackgroundColor = computed(() => {
+ const colorPaletteStore = useColorPaletteStore()
+
+ if (!nodeData.bgcolor) {
+ return ''
+ }
+
+ return applyLightThemeColor(
+ nodeData.bgcolor,
+ Boolean(colorPaletteStore.completedActivePalette.light_theme)
+ )
+})
+
+const nodeOpacity = computed(
+ () => useSettingStore().get('Comfy.Node.Opacity') ?? 1
+)
+
// Use canvas interactions for proper wheel event handling and pointer event capture control
const { handleWheel, shouldHandleNodePointerEvents } = useCanvasInteractions()
diff --git a/src/renderer/extensions/vueNodes/components/NodeHeader.vue b/src/renderer/extensions/vueNodes/components/NodeHeader.vue
index d625a79e5..4f84ff531 100644
--- a/src/renderer/extensions/vueNodes/components/NodeHeader.vue
+++ b/src/renderer/extensions/vueNodes/components/NodeHeader.vue
@@ -4,7 +4,8 @@