From c7582ba34babb7f77a9be4e074568b96cd350195 Mon Sep 17 00:00:00 2001 From: 171696257 <1761696257@qq.com> Date: Tue, 13 May 2025 11:12:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=AC=E6=89=A9=E5=B1=95=E7=8E=B0=E5=B7=B2?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20ComfyUI=20=E5=8E=9F=E7=94=9F=E5=9B=BD?= =?UTF-8?q?=E9=99=85=E5=8C=96=EF=BC=88i18n=EF=BC=89=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=EF=BC=8C=E5=8F=AF=E5=9C=A8=E4=B8=AD=E8=8B=B1=E6=96=87=E9=97=B4?= =?UTF-8?q?=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README-EN.md | 215 +++++++++++ README.md | 23 +- __init__.py | 28 +- js/Intelligent Layout/LayoutCore.js | 152 ++++---- js/Intelligent Layout/LayoutExt.js | 7 +- js/Intelligent Layout/coin.js | 61 ---- js/Intelligent Layout/layoutAlgorithms.js | 421 ---------------------- js/Intelligent Layout/styles.js | 167 --------- locales/en/main.json | 5 + locales/en/nodeDefs.json | 338 +++++++++++++++++ locales/zh/main.json | 5 + locales/zh/nodeDefs.json | 338 +++++++++++++++++ node/advanced_fusion.py | 4 +- node/color_generator.py | 5 + node/condition_switcher.py | 2 +- node/dimension_calculator.py | 5 + node/image_resize.py | 4 +- node/image_size_limiter.py | 4 +- node/image_to_video.py | 2 +- node/latent_switcher.py | 2 +- node/mask_resize.py | 4 +- node/model_optimizer.py | 2 +- node/model_switcher.py | 2 +- node/sampling_optimizer.py | 2 +- node/simple_latent.py | 4 +- pyproject.toml | 2 +- 26 files changed, 1042 insertions(+), 762 deletions(-) create mode 100644 README-EN.md delete mode 100644 js/Intelligent Layout/coin.js delete mode 100644 js/Intelligent Layout/layoutAlgorithms.js delete mode 100644 js/Intelligent Layout/styles.js create mode 100644 locales/en/main.json create mode 100644 locales/en/nodeDefs.json create mode 100644 locales/zh/main.json create mode 100644 locales/zh/nodeDefs.json diff --git a/README-EN.md b/README-EN.md new file mode 100644 index 0000000..4203900 --- /dev/null +++ b/README-EN.md @@ -0,0 +1,215 @@ +# ComfyUI-DD-Nodes + +
+ 中文 | English +
+ +A collection of fully customized ComfyUI nodes developed by Dontdrunk, designed to enhance your workflow with powerful tools and optimizations. + +## Node List + +
+ DD Model Optimizer + DD Sampling Optimizer + +High-performance model loading optimizer with multiple optimization modes: +- Supports standard loading and step-by-step loading methods +- Built-in Smart Mode (automatically selects the best loading solution based on model size and hardware configuration) +- Compatible with all models loaded through UNET nodes + +- First-time sampling speed optimizer, eliminates first sampling delay + +![2131](https://github.com/user-attachments/assets/85c3f36b-f51a-4651-b4f7-9ff0d9f78170) + +
+ +
+ DD Image To Video + +- Efficient image to video frame converter + +![微信截图_20250217231533](https://github.com/user-attachments/assets/66c05a9c-c33b-4813-b434-d3c5928067c5) + +
+ +
+ DD Advanced Fusion + +- Powerful image and video fusion processor + +![QQ2025220-185810-HD 00_00_00-00_00_30](https://github.com/user-attachments/assets/2a50614f-1911-4fd8-bc2e-8d2bece91e73) + +
+ +
+ DD Color Background Generator + +- Advanced color background generator supporting various color modes and layer controls + +![123213](https://github.com/user-attachments/assets/141b1585-0d02-47f1-9d51-2d12eccc6403) + +
+ +
+ DD Dimension Calculator + DD Simple Latent + +- Minimalist image dimension calculator and latent space generator + +![123](https://github.com/user-attachments/assets/dca647bf-1c8f-4947-ad14-c7ad00e98d10) + +
+ +
+ DD Image Uniform Size + DD Mask Uniform Size + +- Multi-functional image, video, and mask size unification processor + +![2](https://github.com/user-attachments/assets/58629a1d-f331-4fd6-aabe-de7158d6fdda) + +
+ +
+ DD Image Size Limiter + +- Smart image size limiter, ensuring images are within specified maximum and minimum size ranges + +![3](https://github.com/user-attachments/assets/d2fac125-fad3-4f51-9b91-39d0be4c7753) + +
+ +
+ DD Switcher Series Nodes + +- Simplify workflows and increase processing flexibility + +![2](https://github.com/user-attachments/assets/54690c0c-3627-4970-9bc0-ef58ca4be2f7) + +
+ +
+ DD Interface Layout + +- Alpha version implemented, can randomly or specifically color node titles, and quickly organize messy workflows into modules + +
+ +
+ DD Node Connection Animation + +Provides various cool animation effects for ComfyUI node connections, supporting customizable styles: +- Supports "Flow", "Wave", "Rhythm", "Pulse" and other animation styles +- Animation parameters are customizable (line width, speed, effects, etc.) + +
+ +## Installation +Method 1 +1. Copy the files to ComfyUI's custom_nodes directory +2. Install dependencies: `pip install -r requirements.txt` +3. Restart ComfyUI + +Method 2 (Recommended) +Use Manager or launcher for installation + +## Language Switching + +This extension now supports ComfyUI's native internationalization (i18n) system, allowing switching between Chinese and English interfaces: + +1. Switch languages: Select language options in the settings menu in the upper right corner of the ComfyUI interface +2. Choose Chinese (zh) or English (en) +3. Currently only supports node translation, frontend functionality translation is not yet supported + +## Version History +- v2.2.0 (2025-05-13) + - Added support for ComfyUI's native internationalization (i18n) system + - Now can seamlessly switch between Chinese and English interfaces + - All node names, descriptions, parameters, and outputs support bilingual display + - Removed modular functionality from the smart layout (may be replaced with custom templates in the future) + +- v2.1.2 (2025-05-12) + - Further improved animation performance and effects, fixed some path bugs in animations + +- v2.1.1 (2025-05-08) + - Fixed compatibility issues between connection animation and the cg-use-everywhere plugin + - When animation is disabled, it will use cg-use-everywhere's animation implementation (refresh browser if not working) + - Fixed a serious bug in the smart layout functionality + +- v2.1.0 (2025-05-08) + - Modularized connection animation effects for easier maintenance and future additions + - Optimized animation performance and algorithms, added animation sampling strength options + - [Low-spec computers: reduce sampling strength and increase animation speed to improve FPS by about 20%] + - Improved pulse animation effects and fixed rhythm effect bugs + - Implemented Alpha version of smart layout functionality (may contain bugs) + +- v2.0.0-F (2025-05-05~06) + - Permanently removed node alignment functionality, with plans for a more powerful interface layout tool + - Changed project to MIT license for full open-source accessibility + +- v2.0.0 (2025-05-04) + - Added "Circuit Board 1" and "Circuit Board 2" connection styles: + - Circuit board implementation references the [quick-connections](https://github.com/niknah/quick-connections) project + - Circuit Board 1: Classic L-shaped/folded paths, compatible with any node layout, fully supports animations and effects + - Circuit Board 2: Supports recursive obstacle avoidance, prioritizes 90/45 degree connections, automatically avoids obstacle nodes + - Both circuit board modes support "Flow", "Wave", "Rhythm", "Pulse" animation styles and gradient effects + +- v1.9.0 (2025-05-03) + - Added a complete set of frontend connection animations + +- v1.8.0 (2025-04-22) + - ┭┮﹏┭┮ + +- v1.7.0 (2025-04-21) + - Added mask uniform size node + - Added image size limiter node + - Added switcher series nodes (Condition, Latent, Model) + +- v1.6.0 (2025-03-05) + - Added image uniform size node + +- v1.5.0 (2025-03-02) + - Added empty Latent video (Wan2.1) [This node has been removed!] + +- v1.4.0 (2025-03-01) + - Added sampling optimizer node for first sampling delay elimination and CLIP text encoding preheating + +- v1.3.0 (2025-02-21) + - Added model optimizer node for UNET model optimization + +- v1.2.0 (2025-02-20) + - Added advanced fusion node for image and video processing + - Added simple latent node + +- v1.1.0 (2025-02-19) + - Optimized color background generator node + - Added layer control features + - Improved mask blending system + +- v1.0.0 (2025-02-17) + - Initial release + - Added color background generator node + - Added dimension calculator node + - Added image to video frame node + - Full Chinese interface support + +## Future Plans + +- Add more image processing nodes +- Add more video processing nodes +- Add workflow assistance nodes +- Continue optimizing existing node performance and functionality + +## Feedback and Suggestions + +This is a growing collection of nodes, primarily for sharing practical ComfyUI extension tools. Feel free to provide suggestions and feedback through Issues. If you find any problems or have any improvement suggestions, please feel free to raise them. + +## License + +MIT + +1. Project growth requires financial support +2. Without donations, the author might: + - 🦥 Stop development + - 😴 Take a long nap + - 🎮 Go play games instead + +Your support is the motivation for the author to continue development! ╭(●`∀´●)╯ +![QR Code](https://github.com/user-attachments/assets/77c99c94-3854-4c12-81cf-09c9f76099ac) diff --git a/README.md b/README.md index f1b781b..297f306 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # ComfyUI-DD-Nodes +
+ 中文 | English +
+ 一个全流程 AI 开发的 ComfyUI 自定义节点集合(完全汉化),由 Dontdrunk 开发维护。 ## 当前节点列表 @@ -100,12 +104,29 @@ ## 安装 - +方法1 1. 将文件复制到 ComfyUI 的 custom_nodes 目录 2. 安装依赖:`pip install -r requirements.txt` 3. 重启 ComfyUI +方法2(推荐) +使用Manager或启动器进行安装 + +## 语言切换 + +本扩展现已支持 ComfyUI 原生国际化(i18n)系统,可在中英文间切换: + +1. 切换语言:在 ComfyUI 界面右上角设置菜单中选择语言选项 +2. 选择中文(zh)或英文(en) +3. 暂时只支持节点翻译,暂不支持前端功能翻译切换 + ## 版本历史 +- v2.2.0 (2025-05-13) +- 添加对 ComfyUI 原生国际化(i18n)系统的支持 +- 现在可以无缝切换中文和英文界面 +- 所有节点名称、描述、参数和输出均支持双语 +- 删除了智能布局的模块化功能(未来可能采用自定义模板) + - v2.1.2 (2025-05-12) - 近一步提升动画性能与效果并修复部分动画的路径BUG。 diff --git a/__init__.py b/__init__.py index 22d4c74..a1dc648 100644 --- a/__init__.py +++ b/__init__.py @@ -29,21 +29,21 @@ NODE_CLASS_MAPPINGS = { **LATENT_SWITCHER_NODES, } -# 节点显示名称映射 +# 节点显示名称映射(使用英文作为默认,中文通过locales提供) NODE_DISPLAY_NAME_MAPPINGS = { - "DD-ColorBackgroundGenerator": "DD 颜色背景生成器", - "DD-DimensionCalculator": "DD 尺寸计算器", - "DD-ImageToVideo": "DD 图片转视频", - "DD-AdvancedFusion": "DD 高级融合", - "DD-SimpleLatent": "DD 极简Latent", - "DD-ModelOptimizer": "DD 模型优化加载", - "DD-SamplingOptimizer": "DD 采样优化器", - "DD-ImageUniformSize": "DD 图像统一尺寸", - "DD-MaskUniformSize": "DD 遮罩统一尺寸", - "DD-ImageSizeLimiter": "DD 限制图像大小", - "DD-ModelSwitcher": "DD 模型切换", - "DD-ConditionSwitcher": "DD 条件切换", - "DD-LatentSwitcher": "DD 潜空间切换", + "DD-ColorBackgroundGenerator": "DD Color Background Generator", + "DD-DimensionCalculator": "DD Dimension Calculator", + "DD-ImageToVideo": "DD Image To Video", + "DD-AdvancedFusion": "DD Advanced Fusion", + "DD-SimpleLatent": "DD Simple Latent", + "DD-ModelOptimizer": "DD Model Optimizer", + "DD-SamplingOptimizer": "DD Sampling Optimizer", + "DD-ImageUniformSize": "DD Image Uniform Size", + "DD-MaskUniformSize": "DD Mask Uniform Size", + "DD-ImageSizeLimiter": "DD Image Size Limiter", + "DD-ModelSwitcher": "DD Model Switcher", + "DD-ConditionSwitcher": "DD Condition Switcher", + "DD-LatentSwitcher": "DD Latent Switcher", } __all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS'] diff --git a/js/Intelligent Layout/LayoutCore.js b/js/Intelligent Layout/LayoutCore.js index f86bd61..920d698 100644 --- a/js/Intelligent Layout/LayoutCore.js +++ b/js/Intelligent Layout/LayoutCore.js @@ -1,7 +1,73 @@ // 智能布局核心模块 -import { RetroCoin } from "./coin.js"; -import { layoutPanelStyles, injectStyles } from "./styles.js"; -import { AutoLayoutEngine, LayoutTools } from "./layoutAlgorithms.js"; + +// 布局面板相关样式 +const layoutPanelStyles = ` + .layout-panel { + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + } + + /* 按钮彩虹动画 */ + @keyframes rainbow { + 0% { background-position: 0% 82% } + 50% { background-position: 100% 19% } + 100% { background-position: 0% 82% } + } + .layout-btn-rainbow:hover { + background-image: linear-gradient(124deg, #ff2400, #e81d1d, #e8b71d, #e3e81d, #1de840, #1ddde8, #2b1de8, #dd00f3, #dd00f3) !important; + background-size: 1800% 1800% !important; + animation: rainbow 6s ease infinite !important; + } + + /* 按钮水波纹效果 */ + .layout-btn::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 5px; + height: 5px; + background: rgba(255, 255, 255, .5); + opacity: 0; + border-radius: 100%; + transform: scale(1, 1) translate(-50%, -50%); + transform-origin: 50% 50%; + } + + .layout-btn:active::after { + animation: ripple 0.6s ease-out; + } + + @keyframes ripple { + 0% { + transform: scale(0, 0) translate(-50%, -50%); + opacity: 0.5; + } + 100% { + transform: scale(20, 20) translate(-50%, -50%); + opacity: 0; + } + } +`; + +// 工具函数:向页面注入样式 +function injectStyles(styleId, styleContent) { + // 如果已经存在相同ID的样式,则不重复注入 + if (document.getElementById(styleId)) return; + + const styleElement = document.createElement('style'); + styleElement.id = styleId; + styleElement.textContent = styleContent; + document.head.appendChild(styleElement); +} + +// 工具函数:移除已注入的样式 +function removeStyles(styleId) { + const styleElement = document.getElementById(styleId); + if (styleElement && styleElement.parentNode) { + styleElement.parentNode.removeChild(styleElement); + } +} // 跟踪鼠标位置 let mousePosition = { x: 0, y: 0 }; @@ -11,15 +77,12 @@ document.addEventListener('mousemove', (e) => { export class LayoutPanel { constructor() { - // 默认启用功能,但UI面板不可见 this.enabled = true; - this.shortcut = 'alt+l'; + this.shortcut = 'alt+x'; this.position = { left: 32, top: 120 }; // 默认位置,将被鼠标位置覆盖 this.visible = false; - this.coin = null; this.container = null; this.buttonsContainer = null; - this.layoutButtonsContainer = null; // 自动排布按钮容器 } setEnabled(enabled) { @@ -92,10 +155,9 @@ export class LayoutPanel { _createPanel() { if (this.container) return; - - // 创建容器 + // 创建容器 this.container = document.createElement('div'); - this.container.className = 'layout-coin-panel'; + this.container.className = 'layout-panel'; this.container.style.position = 'fixed'; this.container.style.left = `${mousePosition.x}px`; this.container.style.top = `${mousePosition.y}px`; @@ -118,16 +180,6 @@ export class LayoutPanel { this.container.style.alignItems = 'center'; this.container.style.gap = '16px'; - // 创建硬币 - this.coin = new RetroCoin({ - onFlip: (side) => { - console.log(`硬币翻转到: ${side}`); - // 这里可以添加翻转后的回调,如执行布局操作 - } - }); - - this.container.appendChild(this.coin.element); - // 创建按钮容器 - 居中对齐 this.buttonsContainer = document.createElement('div'); this.buttonsContainer.className = 'layout-buttons-container'; @@ -158,31 +210,6 @@ export class LayoutPanel { // 添加按钮容器到主容器 this.container.appendChild(this.buttonsContainer); - // 创建自动排布按钮容器 - this.layoutButtonsContainer = document.createElement('div'); - this.layoutButtonsContainer.className = 'layout-auto-buttons-container'; - this.layoutButtonsContainer.style.display = 'flex'; - this.layoutButtonsContainer.style.justifyContent = 'center'; - this.layoutButtonsContainer.style.width = '100%'; - this.layoutButtonsContainer.style.gap = '8px'; - this.layoutButtonsContainer.style.flexWrap = 'wrap'; - - // 只保留模块排布按钮 - const moduleBtn = this._createButton('模块排布', 'layout', '#FF9800'); - moduleBtn.style.flex = '1 1 auto'; - moduleBtn.style.minWidth = '200px'; // 增加宽度,使单个按钮更加突出 - moduleBtn.title = '按功能模块整齐排布节点'; - moduleBtn.addEventListener('click', (e) => { - e.stopPropagation(); - this._applyModuleLayout(); - }); - - // 添加按钮到自动排布容器 - this.layoutButtonsContainer.appendChild(moduleBtn); - - // 添加自动排布按钮容器到主容器 - this.container.appendChild(this.layoutButtonsContainer); - // 使用外部样式模块注入样式 injectStyles('layout-panel-styles', layoutPanelStyles); @@ -194,8 +221,7 @@ export class LayoutPanel { // 添加到文档 document.body.appendChild(this.container); } - - // 创建按钮辅助方法 - 更美观的按钮 + // 创建按钮辅助方法 - 更美观的按钮 _createButton(text, type, bgColor) { const button = document.createElement('button'); button.className = `layout-btn layout-btn-${type}`; @@ -205,7 +231,6 @@ export class LayoutPanel { // 添加更现代的按钮样式 const isPrimary = type === 'pick'; const isRainbow = type === 'rainbow'; - const isLayout = type === 'layout'; // 基础样式 Object.assign(button.style, { @@ -220,7 +245,7 @@ export class LayoutPanel { cursor: 'pointer', transition: 'all 0.2s ease', textShadow: '0 1px 2px rgba(0, 0, 0, 0.2)', - minWidth: isLayout ? '100px' : '120px', + minWidth: '120px', textAlign: 'center', position: 'relative', overflow: 'hidden', @@ -386,33 +411,6 @@ export class LayoutPanel { } } - // 应用模块排布布局 - _applyModuleLayout() { - try { - const app = this._getComfyUIApp(); - if (!app) { - this._showNotification("无法获取ComfyUI应用实例", "error"); - return; - } - - // 创建布局引擎并应用模块排布 - const layoutEngine = new AutoLayoutEngine(app); - const result = layoutEngine.applyModuleLayout(); - - if (result) { - this._showNotification("已应用模块排布,节点按功能分组排列", "info"); - } else { - this._showNotification("无法应用模块排布,请至少选择两个节点", "warn"); - } - - // 应用后隐藏面板 - setTimeout(() => this.hide(), 300); - } catch (error) { - console.error("应用模块排布失败:", error); - this._showNotification("应用模块排布失败: " + error.message, "error"); - } - } - // 获取ComfyUI应用实例 _getComfyUIApp() { if (window.app?.canvas && window.app?.graph) { @@ -536,5 +534,5 @@ export class LayoutPanel { export const DEFAULT_CONFIG = { enabled: true, // 默认启用 - shortcut: 'alt+l' + shortcut: 'alt+x' }; \ No newline at end of file diff --git a/js/Intelligent Layout/LayoutExt.js b/js/Intelligent Layout/LayoutExt.js index aca1e51..57b81f3 100644 --- a/js/Intelligent Layout/LayoutExt.js +++ b/js/Intelligent Layout/LayoutExt.js @@ -96,13 +96,12 @@ app.registerExtension({ }, settings: [ // 移除启用/禁用设置选项 - { - id: "LayoutPanel.shortcut", + { id: "LayoutPanel.shortcut", name: "开关快捷键", type: "text", defaultValue: DEFAULT_CONFIG.shortcut, - tooltip: "弹出智能布局硬币动画面板的快捷键(如alt+l)", - category: ["🍺智能布局", "1·功能", "快捷键"], + tooltip: "弹出节点颜色工具面板的快捷键(如alt+x)", + category: ["🎨节点样式", "1·功能", "快捷键"], onChange(value) { if (typeof value === 'string' && value.includes('+')) { const layoutPanel = getOrCreateLayoutInstance(); diff --git a/js/Intelligent Layout/coin.js b/js/Intelligent Layout/coin.js deleted file mode 100644 index eef09b7..0000000 --- a/js/Intelligent Layout/coin.js +++ /dev/null @@ -1,61 +0,0 @@ -// 独立的复古硬币动画模块 -import { coinStyles, injectStyles } from './styles.js'; - -export class RetroCoin { - constructor(options = {}) { - this.side = options.side === 'devil' ? 'devil' : 'angel'; - this.flipping = false; - this.duration = options.duration || 700; - this.onFlip = typeof options.onFlip === 'function' ? options.onFlip : null; - this.el = this._createCoin(); - } - - _createCoin() { - const container = document.createElement('div'); - container.className = 'coin-container'; - - container.innerHTML = ` -
-
- 👼 -
-
- 😈 -
-
- `; - - // 使用外部样式模块注入样式 - injectStyles('layout-coin-styles', coinStyles); - - // 移除点击呼出/翻转功能,只允许通过面板按钮或快捷键触发 - // container.addEventListener('click', () => this.flip()); - return container; - } - - get element() { - return this.el; - } - - flip() { - if (this.flipping) return; - this.flipping = true; - const coin = this.el.querySelector('.coin'); - const willBeDevil = !coin.classList.contains('flipped'); - coin.classList.toggle('flipped'); - - setTimeout(() => { - this.side = willBeDevil ? 'devil' : 'angel'; - this.flipping = false; - if (this.onFlip) this.onFlip(this.side); - }, this.duration); - } - - setPosition(x, y) { - this.el.style.position = 'absolute'; - this.el.style.left = `${x}px`; - this.el.style.top = `${y}px`; - this.el.style.transform = 'translate(-50%, -50%)'; - this.el.style.zIndex = 100; - } -} diff --git a/js/Intelligent Layout/layoutAlgorithms.js b/js/Intelligent Layout/layoutAlgorithms.js deleted file mode 100644 index 2d31f91..0000000 --- a/js/Intelligent Layout/layoutAlgorithms.js +++ /dev/null @@ -1,421 +0,0 @@ -// 智能布局算法模块 - 提供自动化节点排布功能 -// 包含:模块排布算法 - -// 默认配置 -const AUTO_LAYOUT_CONFIG = { - // 通用设置 - horizontalSpacing: 140, // 水平间距 - verticalSpacing: 80, // 垂直间距 - levelSeparation: 200, // 层级间隔 - nodeWidth: 200, // 默认节点宽度 - nodeHeight: 80, // 默认节点高度 - compactFactor: 0.8, // 紧凑程度(0-1) - - // 模块排布设置 - moduleClusters: { // 模块分组规则 - "loaders": [ - // 基础加载器 - "LoadImage", "LoadVideo", "LoadModel", "VAE", "CLIP", - // 模型加载器 - "CheckpointLoader", "ModelLoader", "Checkpoint", - // Lora相关 - "LoRA", "LoCon", "LoRA_Loader", "LoraLoader", - // 其他常见模型加载器 - "ControlNetLoader", "Upscaler", "Hypernetwork", "Embedding", - // 带有Load前缀或后缀的节点 - "Load", "Loader" - ], - "condition": [ - "CLIPTextEncode", "ConditioningCombine", "ConditioningAverage", "ConditioningConcat", - "Conditioning", "ConditioningSet", "Prompt", "Text", "Encode" - ], - "control": [ - "Control", "ControlNet", "Processor", "Detector", "Estimator", "Depth" - ], - "samplers": [ - "KSampler", "SamplerAdvanced", "Sample", "Sampler", "Sampling" - ], - "latent": [ - "VAEDecode", "VAEEncode", "LatentUpscale", "Latent", "Noise" - ], - "image": [ - "ImageScale", "ImageUpscale", "ImageComposite", "Image", "Img", "Upscale" - ], - "transform": [ - "Transform", "Rotate", "Flip", "Crop", "Resize", "Scale", "Uniform", "Batch" - ], - "effects": [ - "Effect", "Blur", "Sharpen", "Filter", "Enhance", "Color", "Style", "Tint" - ], - "math": [ - "Math", "Add", "Multiply", "Divide", "Subtract", "Calculator", "Formula", "Compute", "Number" - ], - "utils": [ - "Switch", "Switcher", "Select", "Apply", "Join", "Split", "Combine", "Converter", "Convert" - ], - "generator": [ - "Generator", "Generate", "Random", "Pattern", "Noise", "Creator" - ], - "output": [ - "Save", "Output", "Preview", "Display", "Show" - ] - }, - - // 特定节点顺序规则 - 明确定义哪些节点类型应该放在其他节点下方 - nodeOrder: { - // VAEDecode应该在KSampler下方 - "VAEDecode": ["KSampler", "SamplerAdvanced", "Sample", "Sampler", "Sampling"], - "ImageUpscale": ["VAEDecode"] // 图像放大应该在VAE解码下方 - } -}; - -/** - * 自动化布局引擎 - */ -export class AutoLayoutEngine { - constructor(app) { - this.app = app; - this.config = {...AUTO_LAYOUT_CONFIG}; - } - - /** - * 获取选中的节点 - * @returns {Array} 选中的节点数组 - */ - getSelectedNodes() { - if (!this.app?.canvas) return []; - - if (this.app.canvas.selected_nodes?.length) { - return Array.from(this.app.canvas.selected_nodes); - } - - const selectedNodes = []; - if (this.app.graph?._nodes) { - for (const node of this.app.graph._nodes) { - if (node.is_selected) { - selectedNodes.push(node); - } - } - } - - return selectedNodes; - } - - /** - * 获取所有节点 - * @returns {Array} 所有节点数组 - */ - getAllNodes() { - if (!this.app?.graph?._nodes) return []; - return Array.from(this.app.graph._nodes); - } - - /** - * 获取节点之间的连接关系 - * @param {Array} nodes - 节点数组 - * @returns {Object} 节点连接关系图 - */ - buildConnectionGraph(nodes) { - const graph = { - nodes: {}, - links: [], - roots: [], - leaves: [] - }; - - // 初始化节点记录 - nodes.forEach(node => { - graph.nodes[node.id] = { - node, - inputs: [], - outputs: [], - level: -1, - module: this._detectNodeModule(node) - }; - }); - - // 构建连接关系 - nodes.forEach(node => { - if (node.inputs) { - node.inputs.forEach((input, inputIndex) => { - const links = input?.links || []; - links.forEach(linkId => { - const link = this.app.graph.links[linkId]; - if (link) { - const srcNodeId = link.origin_id; - const srcNode = graph.nodes[srcNodeId]; - const targetNode = graph.nodes[node.id]; - - if (srcNode && targetNode) { - srcNode.outputs.push(node.id); - targetNode.inputs.push(srcNodeId); - graph.links.push({ - source: srcNodeId, - target: node.id, - link - }); - } - } - }); - }); - } - }); - - // 确定根节点(没有输入的节点)和叶节点(没有输出的节点) - for (const nodeId in graph.nodes) { - if (graph.nodes[nodeId].inputs.length === 0) { - graph.roots.push(nodeId); - } - if (graph.nodes[nodeId].outputs.length === 0) { - graph.leaves.push(nodeId); - } - } - - return graph; - } - - /** - * 检测节点所属模块 - * @param {Object} node - 节点对象 - * @returns {String} 所属模块名称 - */ - _detectNodeModule(node) { - if (!node.type) return "other"; - - const type = node.type.toLowerCase(); - - for (const [module, nodeTypes] of Object.entries(this.config.moduleClusters)) { - for (const nodeType of nodeTypes) { - if (type.includes(nodeType.toLowerCase())) { - return module; - } - } - } - - return "other"; - } - - /** - * 应用模块排布算法(按功能分组) - * @returns {Boolean} 是否成功应用 - */ - applyModuleLayout() { - try { - const nodes = this.getSelectedNodes().length > 1 ? - this.getSelectedNodes() : this.getAllNodes(); - - if (nodes.length < 2) { - console.log("节点数量不足,无法应用布局"); - return false; - } - - const graph = this.buildConnectionGraph(nodes); - - // 按模块分组节点 - const modules = {}; - for (const nodeId in graph.nodes) { - const module = graph.nodes[nodeId].module; - if (!modules[module]) { - modules[module] = []; - } - modules[module].push(nodeId); - } - - // 调整列布局 - 将latent分组移到samplers分组所在的列,以便VAEDecode能放在KSampler下方 - const columns = [ - ["loaders"], // 第1列:模型加载器 - ["condition", "control"], // 第2列:条件和控制模块 - ["samplers", "latent"], // 第3列:采样器和潜变量(包括VAE解码) - ["transform", "effects", "math"], // 第4列:变换、特效和数学运算 - ["image", "utils", "generator", "output", "other"] // 第5列:图像处理、工具和其他 - ]; - - // 特定节点顺序映射表 - const nodeTypeMapping = {}; - for (const nodeId in graph.nodes) { - const node = graph.nodes[nodeId].node; - const nodeType = node.type; - if (nodeType) { - nodeTypeMapping[nodeId] = nodeType; - } - } - - let xOffset = 0; - - // 处理每一列 - columns.forEach((columnModules, columnIndex) => { - let yOffset = 0; - let maxWidth = 0; - let hasNodes = false; - - // 处理列中的每个模块 - columnModules.forEach(moduleName => { - if (!modules[moduleName] || modules[moduleName].length === 0) return; - hasNodes = true; - - const moduleNodes = modules[moduleName]; - - // 计算模块宽度 - moduleNodes.forEach(nodeId => { - const node = graph.nodes[nodeId].node; - maxWidth = Math.max(maxWidth, node.size[0]); - }); - - // 对于长列,使用更紧凑的垂直间距 - const verticalSpacing = columnIndex === 4 ? - this.config.verticalSpacing * 0.8 : this.config.verticalSpacing; - - // 特殊处理:如果当前模块是samplers或latent,进行特殊排序 - if (moduleName === "samplers" || moduleName === "latent") { - // 按照特定规则排序 - moduleNodes.sort((aId, bId) => { - const aType = nodeTypeMapping[aId] || ""; - const bType = nodeTypeMapping[bId] || ""; - - // 实现特定的排序规则 - // 1. 如果是KSampler类节点,总是排在前面 - // 2. 如果是VAEDecode类节点,总是排在KSampler后面 - - const isASampler = aType.includes("KSampler") || aType.includes("Sampler"); - const isBSampler = bType.includes("KSampler") || bType.includes("Sampler"); - - const isAVAEDecode = aType.includes("VAEDecode"); - const isBVAEDecode = bType.includes("VAEDecode"); - - // K采样器应该排在最前面 - if (isASampler && !isBSampler) return -1; - if (!isASampler && isBSampler) return 1; - - // VAE解码应该排在K采样器之后,其他节点之前 - if (isAVAEDecode && !isBVAEDecode && !isBSampler) return -1; - if (!isAVAEDecode && isBVAEDecode && !isASampler) return 1; - - // 如果都是采样器或都是VAE解码,则按字母顺序排列 - return aId.localeCompare(bId); - }); - } else { - // 默认按照节点ID排序,保持稳定排列 - moduleNodes.sort((a, b) => a.localeCompare(b)); - } - - // 排列模块内的节点 - moduleNodes.forEach(nodeId => { - const node = graph.nodes[nodeId].node; - - // 调整节点大小为统一宽度 - const nodeHeight = node.size[1]; - node.size[0] = maxWidth; - - // 设置节点位置 - node.pos[0] = xOffset; - node.pos[1] = yOffset; - - // 更新下一个节点的垂直位置,长列使用更紧凑的间距 - yOffset += nodeHeight + verticalSpacing; - }); - - // 模块之间添加额外间距,但对于长列减小间距 - yOffset += columnIndex === 4 ? - this.config.verticalSpacing * 0.5 : this.config.verticalSpacing; - }); - - // 只有当列中有节点时才更新水平偏移 - if (hasNodes) { - // 更新下一列的水平位置 - xOffset += maxWidth + this.config.horizontalSpacing * 2; - } - }); - - // 应用变更 - this.app.graph.setDirtyCanvas(true, true); - return true; - } catch (error) { - console.error("应用模块排布失败:", error); - return false; - } - } -} - -// 工具函数 -export const LayoutTools = { - // 获取ComfyUI应用实例 - getAppInstance() { - if (window.app?.canvas && window.app?.graph) { - return window.app; - } - - if (window.LiteGraph?.LGraphCanvas?.active_canvas) { - const canvas = LiteGraph.LGraphCanvas.active_canvas; - if (canvas?.graph) { - return { canvas, graph: canvas.graph }; - } - } - - const canvasElement = document.querySelector(".litegraph.litegraph-canvas"); - if (canvasElement?.lgraphcanvas) { - const canvas = canvasElement.lgraphcanvas; - if (canvas?.graph) { - return { canvas, graph: canvas.graph }; - } - } - - return null; - }, - - // 显示通知 - showNotification(message, type = 'info') { - const notification = document.createElement('div'); - notification.className = 'layout-notification'; - notification.textContent = message; - - Object.assign(notification.style, { - position: 'fixed', - top: '24px', - left: '50%', - transform: 'translateX(-50%)', - padding: '12px 24px', - borderRadius: '8px', - fontSize: '14px', - fontWeight: '500', - zIndex: '10000', - transition: 'all 0.3s ease', - backdropFilter: 'blur(8px)', - boxShadow: '0 8px 24px rgba(0, 0, 0, 0.2)', - border: '1px solid rgba(255, 255, 255, 0.1)', - width: 'auto', - minWidth: '240px', - maxWidth: '90%', - textAlign: 'center', - opacity: '0', - transform: 'translateX(-50%) translateY(-20px)' - }); - - if (type === 'info') { - notification.style.backgroundColor = 'rgba(20, 120, 60, 0.85)'; - notification.style.color = 'white'; - } else if (type === 'warn') { - notification.style.backgroundColor = 'rgba(230, 150, 10, 0.85)'; - notification.style.color = 'white'; - } else { - notification.style.backgroundColor = 'rgba(200, 0, 0, 0.85)'; - notification.style.color = 'white'; - } - - document.body.appendChild(notification); - - setTimeout(() => { - notification.style.opacity = '1'; - notification.style.transform = 'translateX(-50%) translateY(0)'; - }, 10); - - setTimeout(() => { - notification.style.opacity = '0'; - notification.style.transform = 'translateX(-50%) translateY(-20px)'; - setTimeout(() => { - if (notification.parentNode) { - document.body.removeChild(notification); - } - }, 300); - }, 3000); - } -}; \ No newline at end of file diff --git a/js/Intelligent Layout/styles.js b/js/Intelligent Layout/styles.js deleted file mode 100644 index e6bdcbd..0000000 --- a/js/Intelligent Layout/styles.js +++ /dev/null @@ -1,167 +0,0 @@ -// Intelligent Layout 样式模块 -// 统一管理所有CSS样式,方便维护和修改 - -// 硬币相关样式 -export const coinStyles = ` - .coin-container { - position: relative; - width: 90px; - height: 90px; - user-select: none; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - } - .coin { - width: 90px; - height: 90px; - perspective: 600px; - position: relative; - border-radius: 50%; - box-shadow: 0 10px 30px rgba(0,0,0,0.4), 0 0 0 4px #d4b56e inset; - background: radial-gradient(ellipse at 60% 40%, #ffe9b3 60%, #d4b56e 100%); - transition: box-shadow 0.3s; - transform-style: preserve-3d; - transition: transform 0.7s cubic-bezier(.4,2,.6,.9); - } - .coin:active { - box-shadow: 0 5px 15px rgba(0,0,0,0.3), 0 0 0 4px #d4b56e inset; - } - .coin-face { - position: absolute; - width: 100%; - height: 100%; - border-radius: 50%; - backface-visibility: hidden; - display: flex; - align-items: center; - justify-content: center; - font-size: 42px; - font-family: serif; - font-weight: bold; - color: #fffbe6; - text-shadow: 0 2px 8px #d4b56e, 0 0 2px #fffbe6; - box-shadow: 0 0 0 2px #d4b56e inset; - background: radial-gradient(ellipse at 60% 40%, #ffe9b3 70%, #d4b56e 100%); - } - .coin-face-front { - transform: rotateY(0deg); - } - .coin-face-back { - transform: rotateY(180deg); - color: #fff0f0; - text-shadow: 0 2px 8px #a66, 0 0 2px #fff; - background: radial-gradient(ellipse at 40% 60%, #f8c8c8 70%, #a66 100%); - } - .coin.flipped { - animation: coin-flip 0.7s cubic-bezier(.4,2,.6,.9); - transform: rotateY(180deg); - } - .coin:not(.flipped) { - animation: coin-flip-rev 0.7s cubic-bezier(.4,2,.6,.9); - transform: rotateY(0deg); - } - @keyframes coin-flip { - 0% { transform: rotateY(0deg);} - 100% { transform: rotateY(180deg);} - } - @keyframes coin-flip-rev { - 0% { transform: rotateY(180deg);} - 100% { transform: rotateY(0deg);} - } - .coin-angel, .coin-devil { - pointer-events: none; - user-select: none; - font-size: 42px; - } - /* 复古边缘高光增强 */ - .coin::before { - content: ""; - position: absolute; - left: 0; top: 0; width: 100%; height: 100%; - border-radius: 50%; - box-shadow: 0 0 0 6px #e6c97a inset, 0 0 20px 2px #fffbe6 inset; - pointer-events: none; - z-index: 2; - } - /* 3D浮雕感增强 */ - .coin::after { - content: ""; - position: absolute; - left: 10%; top: 10%; width: 80%; height: 80%; - border-radius: 50%; - box-shadow: 0 2px 16px 2px #bfa76a inset, 0 -2px 8px 2px #fffbe6 inset; - pointer-events: none; - z-index: 1; - } -`; - -// 布局面板相关样式 -export const layoutPanelStyles = ` - .layout-coin-panel { - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - } - - /* 按钮彩虹动画 */ - @keyframes rainbow { - 0% { background-position: 0% 82% } - 50% { background-position: 100% 19% } - 100% { background-position: 0% 82% } - } - .layout-btn-rainbow:hover { - background-image: linear-gradient(124deg, #ff2400, #e81d1d, #e8b71d, #e3e81d, #1de840, #1ddde8, #2b1de8, #dd00f3, #dd00f3) !important; - background-size: 1800% 1800% !important; - animation: rainbow 6s ease infinite !important; - } - - /* 按钮水波纹效果 */ - .layout-btn::after { - content: ''; - position: absolute; - top: 50%; - left: 50%; - width: 5px; - height: 5px; - background: rgba(255, 255, 255, .5); - opacity: 0; - border-radius: 100%; - transform: scale(1, 1) translate(-50%, -50%); - transform-origin: 50% 50%; - } - - .layout-btn:active::after { - animation: ripple 0.6s ease-out; - } - - @keyframes ripple { - 0% { - transform: scale(0, 0) translate(-50%, -50%); - opacity: 0.5; - } - 100% { - transform: scale(20, 20) translate(-50%, -50%); - opacity: 0; - } - } -`; - -// 工具函数:向页面注入样式 -export function injectStyles(styleId, styleContent) { - // 如果已经存在相同ID的样式,则不重复注入 - if (document.getElementById(styleId)) return; - - const styleElement = document.createElement('style'); - styleElement.id = styleId; - styleElement.textContent = styleContent; - document.head.appendChild(styleElement); -} - -// 工具函数:移除已注入的样式 -export function removeStyles(styleId) { - const styleElement = document.getElementById(styleId); - if (styleElement && styleElement.parentNode) { - styleElement.parentNode.removeChild(styleElement); - } -} \ No newline at end of file diff --git a/locales/en/main.json b/locales/en/main.json new file mode 100644 index 0000000..f6a4cfd --- /dev/null +++ b/locales/en/main.json @@ -0,0 +1,5 @@ +{ + "nodeCategories": { + "🍺DD系列节点": "DD Series Nodes" + } +} diff --git a/locales/en/nodeDefs.json b/locales/en/nodeDefs.json new file mode 100644 index 0000000..eb1eadb --- /dev/null +++ b/locales/en/nodeDefs.json @@ -0,0 +1,338 @@ +{ + "DD-ColorBackgroundGenerator": { + "display_name": "DD Color Background Generator", + "description": "Generate solid color background images", + "inputs": { + "图层设置": { + "name": "Layer Settings", + "tooltip": "Control layer properties" + }, + "宽度": { + "name": "Width", + "tooltip": "Image width in pixels" + }, + "高度": { + "name": "Height", + "tooltip": "Image height in pixels" + }, + "颜色模式": { + "name": "Color Mode", + "tooltip": "Select color representation mode (HSLA, HSVA, CMYK)" + } + }, + "outputs": { + "0": { + "name": "IMAGE", + "tooltip": "Generated background image" + } + } + }, + "DD-DimensionCalculator": { + "display_name": "DD Dimension Calculator", + "description": "Calculate and adjust image dimension ratios", + "inputs": { + "原始宽度": { + "name": "Original Width", + "tooltip": "Width of the original image" + }, + "原始高度": { + "name": "Original Height", + "tooltip": "Height of the original image" + }, + "缩放比例": { + "name": "Scale Ratio", + "tooltip": "Scaling ratio for resizing" + } + }, + "outputs": { + "0": { + "name": "Width", + "tooltip": "Calculated width" + }, + "1": { + "name": "Height", + "tooltip": "Calculated height" + } + } + }, + "DD-ImageToVideo": { + "display_name": "DD Image To Video", + "description": "Convert images to video frames", + "inputs": { + "图像": { + "name": "Image", + "tooltip": "Input image" + }, + "帧率": { + "name": "FPS", + "tooltip": "Frames per second for the video" + } + }, + "outputs": { + "0": { + "name": "Video Frames", + "tooltip": "Generated video frame sequence" + } + } + }, + "DD-AdvancedFusion": { + "display_name": "DD Advanced Fusion", + "description": "Advanced image fusion techniques", + "inputs": { + "图像A": { + "name": "Image A", + "tooltip": "First input image" + }, + "图像B": { + "name": "Image B", + "tooltip": "Second input image" + }, + "融合强度": { + "name": "Fusion Strength", + "tooltip": "Controls the strength of the fusion effect" + } + }, + "outputs": { + "0": { + "name": "Fused Image", + "tooltip": "The resulting fused image" + } + } + }, + "DD-SimpleLatent": { + "display_name": "DD Simple Latent", + "description": "Simplified latent space operation node", + "inputs": { + "模型": { + "name": "Model", + "tooltip": "Input model" + }, + "提示词": { + "name": "Prompt", + "tooltip": "Text prompt for image generation" + } + }, + "outputs": { + "0": { + "name": "LATENT", + "tooltip": "Generated latent representation" + } + } + }, + "DD-ModelOptimizer": { + "display_name": "DD Model Optimizer", + "description": "Optimize model loading and performance", + "inputs": { + "模型文件": { + "name": "Model File", + "tooltip": "Model file to load" + }, + "智能模式": { + "name": "Smart Mode", + "tooltip": "Whether to use smart optimization mode" + }, + "加载模式": { + "name": "Loading Mode", + "tooltip": "Select model loading method" + }, + "优化模式": { + "name": "Optimization Mode", + "tooltip": "Select model optimization method" + } + }, + "outputs": { + "0": { + "name": "MODEL", + "tooltip": "Optimized model" + } + } + }, + "DD-SamplingOptimizer": { + "display_name": "DD Sampling Optimizer", + "description": "Optimize sampling process performance", + "inputs": { + "模型": { + "name": "Model", + "tooltip": "Model to optimize" + }, + "CLIP模型": { + "name": "CLIP Model", + "tooltip": "CLIP text encoder" + } + }, + "outputs": { + "0": { + "name": "MODEL", + "tooltip": "Optimized model" + }, + "1": { + "name": "CLIP", + "tooltip": "Optimized CLIP" + } + } + }, + "DD-ImageUniformSize": { + "display_name": "DD Image Uniform Size", + "description": "Uniformly resize images", + "inputs": { + "图像": { + "name": "Image", + "tooltip": "Image to resize" + }, + "宽度": { + "name": "Width", + "tooltip": "Target width" + }, + "高度": { + "name": "Height", + "tooltip": "Target height" + } + }, + "outputs": { + "0": { + "name": "IMAGE", + "tooltip": "Resized image" + } + } + }, + "DD-MaskUniformSize": { + "display_name": "DD Mask Uniform Size", + "description": "Uniformly resize masks", + "inputs": { + "遮罩": { + "name": "Mask", + "tooltip": "Mask to resize" + }, + "宽度": { + "name": "Width", + "tooltip": "Target width" + }, + "高度": { + "name": "Height", + "tooltip": "Target height" + } + }, + "outputs": { + "0": { + "name": "MASK", + "tooltip": "Resized mask" + } + } + }, + "DD-ImageSizeLimiter": { + "display_name": "DD Image Size Limiter", + "description": "Limit image dimensions within a specific range", + "inputs": { + "图像": { + "name": "Image", + "tooltip": "Input image" + }, + "最大尺寸": { + "name": "Max Size", + "tooltip": "Maximum dimension of the image" + } + }, + "outputs": { + "0": { + "name": "IMAGE", + "tooltip": "Resized image" + } + } + }, + "DD-ModelSwitcher": { + "display_name": "DD Model Switcher", + "description": "Switch between multiple models", + "inputs": { + "模型1": { + "name": "Model 1", + "tooltip": "First model" + }, + "模型2": { + "name": "Model 2", + "tooltip": "Second model" + }, + "选择输出": { + "name": "Select Output", + "tooltip": "Choose which model to output (1-4)" + }, + "模型3": { + "name": "Model 3", + "tooltip": "Third model (optional)" + }, + "模型4": { + "name": "Model 4", + "tooltip": "Fourth model (optional)" + } + }, + "outputs": { + "0": { + "name": "MODEL", + "tooltip": "Selected model" + } + } + }, + "DD-ConditionSwitcher": { + "display_name": "DD Condition Switcher", + "description": "Switch between multiple conditions", + "inputs": { + "条件1": { + "name": "Condition 1", + "tooltip": "First condition" + }, + "条件2": { + "name": "Condition 2", + "tooltip": "Second condition" + }, + "选择输出": { + "name": "Select Output", + "tooltip": "Choose which condition to output (1-4)" + }, + "条件3": { + "name": "Condition 3", + "tooltip": "Third condition (optional)" + }, + "条件4": { + "name": "Condition 4", + "tooltip": "Fourth condition (optional)" + } + }, + "outputs": { + "0": { + "name": "CONDITIONING", + "tooltip": "Selected condition" + } + } + }, + "DD-LatentSwitcher": { + "display_name": "DD Latent Switcher", + "description": "Switch between multiple latent spaces", + "inputs": { + "潜空间1": { + "name": "Latent 1", + "tooltip": "First latent space" + }, + "潜空间2": { + "name": "Latent 2", + "tooltip": "Second latent space" + }, + "选择输出": { + "name": "Select Output", + "tooltip": "Choose which latent space to output (1-4)" + }, + "潜空间3": { + "name": "Latent 3", + "tooltip": "Third latent space (optional)" + }, + "潜空间4": { + "name": "Latent 4", + "tooltip": "Fourth latent space (optional)" + } + }, + "outputs": { + "0": { + "name": "LATENT", + "tooltip": "Selected latent space" + } + } + } +} diff --git a/locales/zh/main.json b/locales/zh/main.json new file mode 100644 index 0000000..0b9fbae --- /dev/null +++ b/locales/zh/main.json @@ -0,0 +1,5 @@ +{ + "nodeCategories": { + "🍺DD系列节点": "🍺DD系列节点" + } +} diff --git a/locales/zh/nodeDefs.json b/locales/zh/nodeDefs.json new file mode 100644 index 0000000..cb0788e --- /dev/null +++ b/locales/zh/nodeDefs.json @@ -0,0 +1,338 @@ +{ + "DD-ColorBackgroundGenerator": { + "display_name": "DD 颜色背景生成器", + "description": "生成纯色背景图像", + "inputs": { + "图层设置": { + "name": "图层设置", + "tooltip": "控制图层的属性设置" + }, + "宽度": { + "name": "宽度", + "tooltip": "图像宽度(像素)" + }, + "高度": { + "name": "高度", + "tooltip": "图像高度(像素)" + }, + "颜色模式": { + "name": "颜色模式", + "tooltip": "选择颜色表示模式(HSLA, HSVA, CMYK)" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "生成的背景图像" + } + } + }, + "DD-DimensionCalculator": { + "display_name": "DD 尺寸计算器", + "description": "计算和调整图像尺寸比例", + "inputs": { + "原始宽度": { + "name": "原始宽度", + "tooltip": "原始图像的宽度" + }, + "原始高度": { + "name": "原始高度", + "tooltip": "原始图像的高度" + }, + "缩放比例": { + "name": "缩放比例", + "tooltip": "调整大小的缩放比例" + } + }, + "outputs": { + "0": { + "name": "宽度", + "tooltip": "计算后的宽度" + }, + "1": { + "name": "高度", + "tooltip": "计算后的高度" + } + } + }, + "DD-ImageToVideo": { + "display_name": "DD 图片转视频", + "description": "将图像转换为视频帧", + "inputs": { + "图像": { + "name": "图像", + "tooltip": "输入的图像" + }, + "帧率": { + "name": "帧率", + "tooltip": "视频的每秒帧数" + } + }, + "outputs": { + "0": { + "name": "视频帧", + "tooltip": "生成的视频帧序列" + } + } + }, + "DD-AdvancedFusion": { + "display_name": "DD 高级融合", + "description": "高级图像融合技术", + "inputs": { + "图像A": { + "name": "图像A", + "tooltip": "第一个输入图像" + }, + "图像B": { + "name": "图像B", + "tooltip": "第二个输入图像" + }, + "融合强度": { + "name": "融合强度", + "tooltip": "控制融合效果的强度" + } + }, + "outputs": { + "0": { + "name": "融合图像", + "tooltip": "融合后的图像" + } + } + }, + "DD-SimpleLatent": { + "display_name": "DD 极简Latent", + "description": "简化的潜空间操作节点", + "inputs": { + "模型": { + "name": "模型", + "tooltip": "输入的模型" + }, + "提示词": { + "name": "提示词", + "tooltip": "生成图像的提示词" + } + }, + "outputs": { + "0": { + "name": "潜空间", + "tooltip": "生成的潜空间表示" + } + } + }, + "DD-ModelOptimizer": { + "display_name": "DD 模型优化加载", + "description": "优化模型加载和性能", + "inputs": { + "模型文件": { + "name": "模型文件", + "tooltip": "要加载的模型文件" + }, + "智能模式": { + "name": "智能模式", + "tooltip": "是否使用智能优化模式" + }, + "加载模式": { + "name": "加载模式", + "tooltip": "选择模型加载方式" + }, + "优化模式": { + "name": "优化模式", + "tooltip": "选择模型优化方式" + } + }, + "outputs": { + "0": { + "name": "优化模型", + "tooltip": "优化后的模型" + } + } + }, + "DD-SamplingOptimizer": { + "display_name": "DD 采样优化器", + "description": "优化采样过程性能", + "inputs": { + "模型": { + "name": "模型", + "tooltip": "要优化的模型" + }, + "CLIP模型": { + "name": "CLIP模型", + "tooltip": "CLIP文本编码器" + } + }, + "outputs": { + "0": { + "name": "优化模型", + "tooltip": "优化后的模型" + }, + "1": { + "name": "优化CLIP", + "tooltip": "优化后的CLIP" + } + } + }, + "DD-ImageUniformSize": { + "display_name": "DD 图像统一尺寸", + "description": "统一调整图像尺寸", + "inputs": { + "图像": { + "name": "图像", + "tooltip": "要调整的图像" + }, + "宽度": { + "name": "宽度", + "tooltip": "目标宽度" + }, + "高度": { + "name": "高度", + "tooltip": "目标高度" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "调整尺寸后的图像" + } + } + }, + "DD-MaskUniformSize": { + "display_name": "DD 遮罩统一尺寸", + "description": "统一调整遮罩尺寸", + "inputs": { + "遮罩": { + "name": "遮罩", + "tooltip": "要调整的遮罩" + }, + "宽度": { + "name": "宽度", + "tooltip": "目标宽度" + }, + "高度": { + "name": "高度", + "tooltip": "目标高度" + } + }, + "outputs": { + "0": { + "name": "遮罩", + "tooltip": "调整尺寸后的遮罩" + } + } + }, + "DD-ImageSizeLimiter": { + "display_name": "DD 限制图像大小", + "description": "限制图像尺寸在特定范围内", + "inputs": { + "图像": { + "name": "图像", + "tooltip": "输入图像" + }, + "最大尺寸": { + "name": "最大尺寸", + "tooltip": "图像的最大边长" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "调整后的图像" + } + } + }, + "DD-ModelSwitcher": { + "display_name": "DD 模型切换", + "description": "在多个模型之间进行切换", + "inputs": { + "模型1": { + "name": "模型1", + "tooltip": "第一个模型" + }, + "模型2": { + "name": "模型2", + "tooltip": "第二个模型" + }, + "选择输出": { + "name": "选择输出", + "tooltip": "选择输出哪个模型(1-4)" + }, + "模型3": { + "name": "模型3", + "tooltip": "第三个模型(可选)" + }, + "模型4": { + "name": "模型4", + "tooltip": "第四个模型(可选)" + } + }, + "outputs": { + "0": { + "name": "模型", + "tooltip": "选中的模型" + } + } + }, + "DD-ConditionSwitcher": { + "display_name": "DD 条件切换", + "description": "在多个条件之间进行切换", + "inputs": { + "条件1": { + "name": "条件1", + "tooltip": "第一个条件" + }, + "条件2": { + "name": "条件2", + "tooltip": "第二个条件" + }, + "选择输出": { + "name": "选择输出", + "tooltip": "选择输出哪个条件(1-4)" + }, + "条件3": { + "name": "条件3", + "tooltip": "第三个条件(可选)" + }, + "条件4": { + "name": "条件4", + "tooltip": "第四个条件(可选)" + } + }, + "outputs": { + "0": { + "name": "条件", + "tooltip": "选中的条件" + } + } + }, + "DD-LatentSwitcher": { + "display_name": "DD 潜空间切换", + "description": "在多个潜空间之间进行切换", + "inputs": { + "潜空间1": { + "name": "潜空间1", + "tooltip": "第一个潜空间" + }, + "潜空间2": { + "name": "潜空间2", + "tooltip": "第二个潜空间" + }, + "选择输出": { + "name": "选择输出", + "tooltip": "选择输出哪个潜空间(1-4)" + }, + "潜空间3": { + "name": "潜空间3", + "tooltip": "第三个潜空间(可选)" + }, + "潜空间4": { + "name": "潜空间4", + "tooltip": "第四个潜空间(可选)" + } + }, + "outputs": { + "0": { + "name": "潜空间", + "tooltip": "选中的潜空间" + } + } + } +} diff --git a/node/advanced_fusion.py b/node/advanced_fusion.py index 4dfd131..ed68781 100644 --- a/node/advanced_fusion.py +++ b/node/advanced_fusion.py @@ -231,7 +231,7 @@ NODE_CLASS_MAPPINGS = { "DD-AdvancedFusion": DDAdvancedFusion } -# 节点显示名称映射 +# 节点显示名称映射 - 使用英文(中文通过locales提供) NODE_DISPLAY_NAME_MAPPINGS = { - "DD-AdvancedFusion": "DD 高级融合" + "DD-AdvancedFusion": "DD Advanced Fusion" } diff --git a/node/color_generator.py b/node/color_generator.py index 6b44a13..7cc1435 100644 --- a/node/color_generator.py +++ b/node/color_generator.py @@ -232,3 +232,8 @@ class ColorBackgroundGenerator: NODE_CLASS_MAPPINGS = { "DD-ColorBackgroundGenerator": ColorBackgroundGenerator } + +# 节点显示名称映射 - 使用英文(中文通过locales提供) +NODE_DISPLAY_NAME_MAPPINGS = { + "DD-ColorBackgroundGenerator": "DD Color Background Generator" +} diff --git a/node/condition_switcher.py b/node/condition_switcher.py index 01ba4f2..6bc28e3 100644 --- a/node/condition_switcher.py +++ b/node/condition_switcher.py @@ -59,5 +59,5 @@ NODE_CLASS_MAPPINGS = { # 节点显示名称映射 NODE_DISPLAY_NAME_MAPPINGS = { - "DD-ConditionSwitcher": "DD 条件切换" + "DD-ConditionSwitcher": "DD Condition Switcher" } \ No newline at end of file diff --git a/node/dimension_calculator.py b/node/dimension_calculator.py index 2b2545e..585866d 100644 --- a/node/dimension_calculator.py +++ b/node/dimension_calculator.py @@ -20,3 +20,8 @@ class DimensionCalculator: NODE_CLASS_MAPPINGS = { "DD-DimensionCalculator": DimensionCalculator } + +# 节点显示名称映射 - 使用英文(中文通过locales提供) +NODE_DISPLAY_NAME_MAPPINGS = { + "DD-DimensionCalculator": "DD Dimension Calculator" +} diff --git a/node/image_resize.py b/node/image_resize.py index 7200619..158036e 100644 --- a/node/image_resize.py +++ b/node/image_resize.py @@ -256,7 +256,7 @@ NODE_CLASS_MAPPINGS = { "DD-ImageUniformSize": DDImageUniformSize } -# 节点显示名称映射 +# 节点显示名称映射 - 使用英文(中文通过locales提供) NODE_DISPLAY_NAME_MAPPINGS = { - "DD-ImageUniformSize": "DD 图像统一尺寸" + "DD-ImageUniformSize": "DD Image Uniform Size" } diff --git a/node/image_size_limiter.py b/node/image_size_limiter.py index 8c8efcc..06490d0 100644 --- a/node/image_size_limiter.py +++ b/node/image_size_limiter.py @@ -238,7 +238,7 @@ NODE_CLASS_MAPPINGS = { "DD-ImageSizeLimiter": DDImageSizeLimiter } -# 节点显示名称映射 +# 节点显示名称映射 - 使用英文(中文通过locales提供) NODE_DISPLAY_NAME_MAPPINGS = { - "DD-ImageSizeLimiter": "DD 限制图像大小" + "DD-ImageSizeLimiter": "DD Image Size Limiter" } diff --git a/node/image_to_video.py b/node/image_to_video.py index fa68a17..1250cf6 100644 --- a/node/image_to_video.py +++ b/node/image_to_video.py @@ -88,5 +88,5 @@ NODE_CLASS_MAPPINGS = { } NODE_DISPLAY_NAME_MAPPINGS = { - "DD-ImageToVideo": "DD 图片转视频帧" + "DD-ImageToVideo": "DD Image To Video" } diff --git a/node/latent_switcher.py b/node/latent_switcher.py index 5a92ca2..c13a93b 100644 --- a/node/latent_switcher.py +++ b/node/latent_switcher.py @@ -59,5 +59,5 @@ NODE_CLASS_MAPPINGS = { # 节点显示名称映射 NODE_DISPLAY_NAME_MAPPINGS = { - "DD-LatentSwitcher": "DD 潜空间切换" + "DD-LatentSwitcher": "DD Latent Switcher" } \ No newline at end of file diff --git a/node/mask_resize.py b/node/mask_resize.py index 3f4474c..8a5e8cc 100644 --- a/node/mask_resize.py +++ b/node/mask_resize.py @@ -283,7 +283,7 @@ NODE_CLASS_MAPPINGS = { "DD-MaskUniformSize": DDMaskUniformSize } -# 节点显示名称映射 +# 节点显示名称映射 - 使用英文(中文通过locales提供) NODE_DISPLAY_NAME_MAPPINGS = { - "DD-MaskUniformSize": "DD 遮罩统一尺寸" + "DD-MaskUniformSize": "DD Mask Uniform Size" } diff --git a/node/model_optimizer.py b/node/model_optimizer.py index 33c5c71..250761c 100644 --- a/node/model_optimizer.py +++ b/node/model_optimizer.py @@ -239,5 +239,5 @@ NODE_CLASS_MAPPINGS = { } NODE_DISPLAY_NAME_MAPPINGS = { - "DD-ModelOptimizer": "DD 模型优化加载" + "DD-ModelOptimizer": "DD Model Optimizer" } diff --git a/node/model_switcher.py b/node/model_switcher.py index f358544..3842fff 100644 --- a/node/model_switcher.py +++ b/node/model_switcher.py @@ -59,5 +59,5 @@ NODE_CLASS_MAPPINGS = { # 节点显示名称映射 NODE_DISPLAY_NAME_MAPPINGS = { - "DD-ModelSwitcher": "DD 模型切换" + "DD-ModelSwitcher": "DD Model Switcher" } \ No newline at end of file diff --git a/node/sampling_optimizer.py b/node/sampling_optimizer.py index f391311..a908787 100644 --- a/node/sampling_optimizer.py +++ b/node/sampling_optimizer.py @@ -154,5 +154,5 @@ NODE_CLASS_MAPPINGS = { # 节点显示名称映射 NODE_DISPLAY_NAME_MAPPINGS = { - "DD-SamplingOptimizer": "DD 采样优化器" + "DD-SamplingOptimizer": "DD Sampling Optimizer" } diff --git a/node/simple_latent.py b/node/simple_latent.py index ae427be..f60c540 100644 --- a/node/simple_latent.py +++ b/node/simple_latent.py @@ -47,7 +47,7 @@ NODE_CLASS_MAPPINGS = { "DD-SimpleLatent": DDSimpleLatent } -# 节点显示名称映射 +# 节点显示名称映射 - 使用英文(中文通过locales提供) NODE_DISPLAY_NAME_MAPPINGS = { - "DD-SimpleLatent": "DD 极简Latent" + "DD-SimpleLatent": "DD Simple Latent" } diff --git a/pyproject.toml b/pyproject.toml index 6947602..49890b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-dd-nodes" description = "Advanced utility nodes for ComfyUI with intelligent layout and animation features." -version = "2.1.2" +version = "2.2.0" license = {file = "LICENSE"} dependencies = ["git+https://github.com/Dontdrunk/ComfyUI-DD-Nodes.git"]