From 42c130d071d75ef7a4fe06d7b8ab06b263bc4767 Mon Sep 17 00:00:00 2001 From: bymyself Date: Sat, 27 Sep 2025 10:52:00 -0700 Subject: [PATCH] [feat] fully replicate LiteGraph drawNode color logic in Vue nodes Now correctly implements all aspects of the LiteGraph drawNode monkey patch: 1. Header colors: Apply opacity + lightness adjustments like LiteGraph 2. Body colors: Apply same adjustments to background as LiteGraph 3. Opacity setting: Support 'Comfy.Node.Opacity' setting from user preferences 4. Light theme: Apply lightness=0.5 to both header and body in light theme This ensures Vue nodes have pixel-perfect color matching with LiteGraph nodes across all themes and opacity settings. --- .../vueNodes/components/LGraphNode.vue | 36 ++++++++++++++++++- .../vueNodes/components/NodeHeader.vue | 28 ++++++++++----- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/renderer/extensions/vueNodes/components/LGraphNode.vue b/src/renderer/extensions/vueNodes/components/LGraphNode.vue index f4d8f79a3..a1a2d16ec 100644 --- a/src/renderer/extensions/vueNodes/components/LGraphNode.vue +++ b/src/renderer/extensions/vueNodes/components/LGraphNode.vue @@ -35,7 +35,7 @@ { transform: `translate(${position.x ?? 0}px, ${(position.y ?? 0) - LiteGraph.NODE_TITLE_HEIGHT}px)`, zIndex: zIndex, - backgroundColor: nodeData.bgcolor || '' + backgroundColor: nodeBodyBackgroundColor }, dragStyle ]" @@ -145,6 +145,7 @@ import type { VueNodeData } from '@/composables/graph/useGraphNodeManager' import { toggleNodeOptions } from '@/composables/graph/useMoreOptionsMenu' import { useErrorHandling } from '@/composables/useErrorHandling' import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { useSettingStore } from '@/platform/settings/settingStore' import { useCanvasStore } from '@/renderer/core/canvas/canvasStore' import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions' import { TransformStateKey } from '@/renderer/core/layout/injectionKeys' @@ -157,6 +158,8 @@ import { useNodePreviewState } from '@/renderer/extensions/vueNodes/preview/useN import { app } from '@/scripts/app' import { useExecutionStore } from '@/stores/executionStore' import { useNodeOutputStore } from '@/stores/imagePreviewStore' +import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore' +import { adjustColor } from '@/utils/colorUtil' import { getLocatorIdFromNodeData, getNodeByLocatorId @@ -227,6 +230,37 @@ const hasAnyError = computed((): boolean => { const bypassed = computed((): boolean => nodeData.mode === 4) const muted = computed((): boolean => nodeData.mode === 2) // NEVER mode +// Node body background color that exactly replicates LiteGraph's drawNode logic +const nodeBodyBackgroundColor = computed(() => { + const colorPaletteStore = useColorPaletteStore() + const settingStore = useSettingStore() + + // This replicates the drawNode logic for bgColor + let bgColor = nodeData.bgcolor || '' // matches: old_bgcolor || LiteGraph.NODE_DEFAULT_BGCOLOR + + if (!bgColor) return '' // No color to adjust + + // Apply the exact same adjustments as the drawNode monkey patch + const adjustments: { lightness?: number; opacity?: number } = {} + + // 1. Apply opacity setting (same as drawNode) + const opacity = settingStore.get('Comfy.Node.Opacity') + if (opacity) adjustments.opacity = opacity + + // 2. Apply light theme background lightening (same as drawNode) + if (colorPaletteStore.completedActivePalette.light_theme) { + // This matches: "if (old_bgcolor) adjustments.lightness = 0.5" + adjustments.lightness = 0.5 + } + + // Apply all adjustments at once: node.bgcolor = adjustColor(bgColor, adjustments) + if (Object.keys(adjustments).length > 0) { + bgColor = adjustColor(bgColor, adjustments) + } + + return bgColor +}) + // 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 70b61e065..8b959f776 100644 --- a/src/renderer/extensions/vueNodes/components/NodeHeader.vue +++ b/src/renderer/extensions/vueNodes/components/NodeHeader.vue @@ -72,6 +72,7 @@ import EditableText from '@/components/common/EditableText.vue' import type { VueNodeData } from '@/composables/graph/useGraphNodeManager' import { useErrorHandling } from '@/composables/useErrorHandling' import { st } from '@/i18n' +import { useSettingStore } from '@/platform/settings/settingStore' import { useNodeTooltips } from '@/renderer/extensions/vueNodes/composables/useNodeTooltips' import { app } from '@/scripts/app' import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore' @@ -126,25 +127,34 @@ const tooltipConfig = computed(() => { return createTooltipConfig(description) }) -// Header style that replicates LiteGraph's ColorOption and drawNode logic +// Header style that exactly replicates LiteGraph's drawNode monkey patch logic const headerStyle = computed(() => { if (!nodeData?.color) { return { backgroundColor: '' } // Explicitly clear background color } const colorPaletteStore = useColorPaletteStore() + const settingStore = useSettingStore() + + // Start with the original color (same as old_color in drawNode) let headerColor = nodeData.color - // Apply base header darkening to replicate LiteGraph's ColorOption system - // When header and body colors are the same/similar, darken the header - if (nodeData.bgcolor && nodeData.color === nodeData.bgcolor) { - // Darken header relative to body (opposite of light theme adjustment) - headerColor = adjustColor(nodeData.color, { lightness: -0.15 }) + // Apply the exact same adjustments as the drawNode monkey patch + const adjustments: { lightness?: number; opacity?: number } = {} + + // 1. Apply opacity setting (same as drawNode) + const opacity = settingStore.get('Comfy.Node.Opacity') + if (opacity) adjustments.opacity = opacity + + // 2. Apply light theme adjustments (same as drawNode) + if (colorPaletteStore.completedActivePalette.light_theme) { + // This matches: "if (old_color) { node.color = adjustColor(old_color, { lightness: 0.5 }) }" + adjustments.lightness = 0.5 } - // Apply light theme lightening on top of base darkening (same as drawNode monkey patch) - if (colorPaletteStore.completedActivePalette.light_theme) { - headerColor = adjustColor(headerColor, { lightness: 0.5 }) + // Apply all adjustments at once (matching drawNode's approach) + if (Object.keys(adjustments).length > 0) { + headerColor = adjustColor(headerColor, adjustments) } return { backgroundColor: headerColor }