ComfyUIのプログレスバー
はじめに
これはComfyUIフロントエンドのGraphCanvasMenu
へのパッチと、UIに2つのプログレスバーを追加するProgressBars
の実装です。
機能
この実装は、ComfyUIインターフェースに2つの異なるプログレスバーを追加します。1つ目は全体的なワークフローの実行進捗を表示するワークフロープログレスバーで、2つ目は現在実行中のノードの進捗を表示するノードプログレスバーです。
これらのプログレスバーは、ユーザーエクスペリエンスを考慮して慎重に設計されています - それぞれ2pxと1pxという最小限の高さで非侵襲的な存在感を維持し、ライトテーマとダークテーマの両方にシームレスに適応し、システムがアイドル状態のときは自動的に非表示になってインターフェースをクリーンで整然とした状態に保ちます。
実装の詳細
コンポーネント構造
プログレスバーは、メインキャンバスと一緒にマウントされるVueコンポーネント(GraphProgressBars.vue
)として実装されています。このコンポーネントは、UIでプログレスインジケーターを表示および管理するために必要な基本構造を提供します。
コンポーネントは、両方のプログレスバーとそれぞれの塗りつぶしインジケーターを収容するコンテナdivで構築され、実行ストアへのリアクティブバインディングを利用してワークフロー実行中のリアルタイムな進捗追跡を可能にします。
プログレスバーの状態
プログレスバーは、実行ストアからの3つの主要な状態に応答します:
executionProgress
:全体的なワークフローの進捗(0-100%)executingNodeProgress
:現在のノードの進捗(0-100%)isIdle
:処理が行われているかどうか
ビジュアルデザイン
プログレスバーは0.2秒のイーズアウトアニメーションによるスムーズな遷移を組み込み、ワークフローバーが2px、ノードバーが1pxという異なる高さによる視覚的階層を特徴としています。また、目的を区別するために異なる色を使用し、ワークフローの進捗は青色(#3498db)、ノードの進捗は緑色(#2ecc71)で表示されます。
プログレスバーはテーマに応じて適応するように設計されており、UIテーマに基づいて背景が変化します - ライトテーマでは半透明の黒、ダークテーマでは半透明の白を使用します。これにより、ユーザーのテーマ設定に関係なく最適な視認性が確保されます。
インストール
プログレスバーをComfyUIインストールに追加するには:
GraphCanvas.vue
にパッチを適用します:patch -p1 < GraphCanvasMenu_progressbars.patch
GraphProgressBars.vue
コンポーネントをプロジェクトのcomponentsディレクトリに追加します:src/components/graph/GraphProgressBars.vue
フロントエンドを再ビルドします。
使用方法
プログレスバーは以下の場合に自動的に表示されます:
- ワークフローが実行中(上部バー)
- 個々のノードが処理中(下部バー)
システムがアイドル状態に戻ると自動的に非表示になり、必要のないときはインターフェースをクリーンに保ちます。
技術的な注意点
コンポーネントは、状態管理のためにexecutionStore
を通じてPiniaを活用しています。プログレスバーが他のインターフェース要素の上に表示され続けるようにするため、z-index
が1000の絶対位置に配置されています。実装では、プログレスバーが下に配置されたUI要素と干渉しないように、pointer-events-noneを使用しています。
コード
GraphCanvasMenu_progressbars.patch
diff --git a/src/components/graph/GraphCanvas.vue b/src/components/graph/GraphCanvas.vue index 127a6b20..7e6a6840 100644 --- a/src/components/graph/GraphCanvas.vue +++ b/src/components/graph/GraphCanvas.vue @@ -18,6 +18,7 @@ </LiteGraphCanvasSplitterOverlay> <TitleEditor /> <GraphCanvasMenu v-if="!betaMenuEnabled && canvasMenuEnabled" /> + <GraphProgressBars /> <canvas ref="canvasRef" id="graph-canvas" tabindex="1" /> </teleport> <NodeSearchboxPopover /> @@ -33,6 +34,7 @@ import LiteGraphCanvasSplitterOverlay from '@/components/LiteGraphCanvasSplitter import NodeSearchboxPopover from '@/components/searchbox/NodeSearchBoxPopover.vue' import NodeTooltip from '@/components/graph/NodeTooltip.vue' import NodeBadge from '@/components/graph/NodeBadge.vue' +import GraphProgressBars from '@/components/graph/GraphProgressBars.vue' import { ref, computed, onMounted, watchEffect, watch } from 'vue' import { app as comfyApp } from '@/scripts/app' import { useSettingStore } from '@/stores/settingStore'
/src/components/graph/GraphProgressBars.vue
<template> <div class="graph-progress-bars" v-show="!isIdle"> <!-- ワークフロープログレスバー --> <div class="progress-bar workflow-progress"> <div class="progress-fill" :style="{ width: executionProgress + '%' }" /> </div> <!-- ノードプログレスバー --> <div class="progress-bar node-progress" v-show="executingNodeProgress !== null" > <div class="progress-fill" :style="{ width: executingNodeProgress + '%' }" /> </div> </div> </template> <script setup lang="ts"> import { useExecutionStore } from '@/stores/executionStore' import { storeToRefs } from 'pinia' const executionStore = useExecutionStore() const { executionProgress, executingNodeProgress, isIdle } = storeToRefs(executionStore) </script> <style scoped> .graph-progress-bars { position: absolute; top: 0; left: 0; right: 0; z-index: 1000; pointer-events: none; } .progress-bar { width: 100%; height: 2px; background: rgba(0, 0, 0, 0.1); overflow: hidden; } .progress-bar.node-progress { height: 1px; background: rgba(0, 0, 0, 0.05); } .progress-fill { height: 100%; background: #3498db; transition: width 0.2s ease-out; } .node-progress .progress-fill { background: #2ecc71; } /* ダークテーマのサポート */ :root[data-theme='dark'] .progress-bar { background: rgba(255, 255, 255, 0.1); } :root[data-theme='dark'] .progress-bar.node-progress { background: rgba(255, 255, 255, 0.05); } </style>