mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-21 23:09:39 +00:00
[refactor] Improve renderer domain organization (#5552)
* [refactor] Improve renderer architecture organization Building on PR #5388, this refines the renderer domain structure: **Key improvements:** - Group all transform utilities in `transform/` subdirectory for better cohesion - Move canvas state to dedicated `renderer/core/canvas/` domain - Consolidate coordinate system logic (TransformPane, useTransformState, sync utilities) **File organization:** - `renderer/core/canvas/canvasStore.ts` (was `stores/graphStore.ts`) - `renderer/core/layout/transform/` contains all coordinate system utilities - Transform sync utilities co-located with core transform logic This creates clearer domain boundaries and groups related functionality while building on the foundation established in PR #5388. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Clean up linter-modified files * Fix import paths and clean up unused imports after rebase - Update all remaining @/stores/graphStore references to @/renderer/core/canvas/canvasStore - Remove unused imports from selection toolbox components - All tests pass, only reka-ui upstream issue remains in typecheck 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * [auto-fix] Apply ESLint and Prettier fixes --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
110
src/renderer/core/canvas/canvasStore.ts
Normal file
110
src/renderer/core/canvas/canvasStore.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { type Raw, computed, markRaw, ref, shallowRef } from 'vue'
|
||||
|
||||
import type { Point, Positionable } from '@/lib/litegraph/src/interfaces'
|
||||
import type {
|
||||
LGraphCanvas,
|
||||
LGraphGroup,
|
||||
LGraphNode
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import { app } from '@/scripts/app'
|
||||
import { isLGraphGroup, isLGraphNode, isReroute } from '@/utils/litegraphUtil'
|
||||
|
||||
export const useTitleEditorStore = defineStore('titleEditor', () => {
|
||||
const titleEditorTarget = shallowRef<LGraphNode | LGraphGroup | null>(null)
|
||||
|
||||
return {
|
||||
titleEditorTarget
|
||||
}
|
||||
})
|
||||
|
||||
export const useCanvasStore = defineStore('canvas', () => {
|
||||
/**
|
||||
* The LGraphCanvas instance.
|
||||
*
|
||||
* The root LGraphCanvas object is a shallow ref.
|
||||
*/
|
||||
const canvas = shallowRef<LGraphCanvas | null>(null)
|
||||
/**
|
||||
* The selected items on the canvas. All stored items are raw.
|
||||
*/
|
||||
const selectedItems = ref<Raw<Positionable>[]>([])
|
||||
const updateSelectedItems = () => {
|
||||
const items = Array.from(canvas.value?.selectedItems ?? [])
|
||||
selectedItems.value = items.map((item) => markRaw(item))
|
||||
}
|
||||
|
||||
// Reactive scale percentage that syncs with app.canvas.ds.scale
|
||||
const appScalePercentage = ref(100)
|
||||
|
||||
// Set up scale synchronization when canvas is available
|
||||
let originalOnChanged: ((scale: number, offset: Point) => void) | undefined =
|
||||
undefined
|
||||
const initScaleSync = () => {
|
||||
if (app.canvas?.ds) {
|
||||
// Initial sync
|
||||
originalOnChanged = app.canvas.ds.onChanged
|
||||
appScalePercentage.value = Math.round(app.canvas.ds.scale * 100)
|
||||
|
||||
// Set up continuous sync
|
||||
app.canvas.ds.onChanged = () => {
|
||||
if (app.canvas?.ds?.scale) {
|
||||
appScalePercentage.value = Math.round(app.canvas.ds.scale * 100)
|
||||
}
|
||||
// Call original handler if exists
|
||||
originalOnChanged?.(app.canvas.ds.scale, app.canvas.ds.offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const cleanupScaleSync = () => {
|
||||
if (app.canvas?.ds) {
|
||||
app.canvas.ds.onChanged = originalOnChanged
|
||||
originalOnChanged = undefined
|
||||
}
|
||||
}
|
||||
|
||||
const nodeSelected = computed(() => selectedItems.value.some(isLGraphNode))
|
||||
const groupSelected = computed(() => selectedItems.value.some(isLGraphGroup))
|
||||
const rerouteSelected = computed(() => selectedItems.value.some(isReroute))
|
||||
|
||||
const getCanvas = () => {
|
||||
if (!canvas.value) throw new Error('getCanvas: canvas is null')
|
||||
return canvas.value
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the canvas zoom level from a percentage value
|
||||
* @param percentage - Zoom percentage value (1-1000, where 1000 = 1000% zoom)
|
||||
*/
|
||||
const setAppZoomFromPercentage = (percentage: number) => {
|
||||
if (!app.canvas?.ds || percentage <= 0) return
|
||||
|
||||
// Convert percentage to scale (1000% = 10.0 scale)
|
||||
const newScale = percentage / 100
|
||||
const ds = app.canvas.ds
|
||||
|
||||
ds.changeScale(
|
||||
newScale,
|
||||
ds.element ? [ds.element.width / 2, ds.element.height / 2] : undefined
|
||||
)
|
||||
app.canvas.setDirty(true, true)
|
||||
|
||||
// Update reactive value immediately for UI consistency
|
||||
appScalePercentage.value = Math.round(newScale * 100)
|
||||
}
|
||||
|
||||
return {
|
||||
canvas,
|
||||
selectedItems,
|
||||
nodeSelected,
|
||||
groupSelected,
|
||||
rerouteSelected,
|
||||
appScalePercentage,
|
||||
updateSelectedItems,
|
||||
getCanvas,
|
||||
setAppZoomFromPercentage,
|
||||
initScaleSync,
|
||||
cleanupScaleSync
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user