mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
selection rectangle for vueNodes (#7088)
## Summary fix: render selection rectangle in DOM layer for Vue nodes mode. When Vue nodes are enabled, the canvas selection rectangle was being rendered behind Vue node elements due to DOM stacking order (canvas layer is below the TransformPane layer). ## Changes - Adds a new SelectionRectangle.vue component that renders the selection box as a DOM element - Places it above the Vue nodes layer so it's always visible during drag selection - Skips canvas-based selection rectangle rendering when Vue nodes mode is active - Bonus: adds a semi-transparent blue fill style for better visibility ## Screenshots before https://github.com/user-attachments/assets/a8ee2ca3-00fd-4fdc-925a-dc9f846f4280 after https://github.com/user-attachments/assets/66b7f2f5-f0a0-486f-9556-3872d07d65be One more thing, the following improvement will be live selection, something like: https://github.com/user-attachments/assets/05a2b7ea-89b1-4568-bd2a-792f4fc11d8e but I don't want to increase this PR, so I will send live selection after this selection rectangle ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7088-selection-rectangle-for-vueNodes-2bd6d73d3650817aa2e9cf4526f179d8) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -77,6 +77,9 @@
|
||||
/>
|
||||
</TransformPane>
|
||||
|
||||
<!-- Selection rectangle overlay for Vue nodes mode -->
|
||||
<SelectionRectangle v-if="shouldRenderVueNodes && comfyAppReady" />
|
||||
|
||||
<NodeTooltip v-if="tooltipEnabled" />
|
||||
<NodeSearchboxPopover ref="nodeSearchboxPopoverRef" />
|
||||
|
||||
@@ -159,6 +162,7 @@ import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
import { isNativeWindow } from '@/utils/envUtil'
|
||||
|
||||
import TryVueNodeBanner from '../topbar/TryVueNodeBanner.vue'
|
||||
import SelectionRectangle from './SelectionRectangle.vue'
|
||||
|
||||
const emit = defineEmits<{
|
||||
ready: []
|
||||
|
||||
63
src/components/graph/SelectionRectangle.vue
Normal file
63
src/components/graph/SelectionRectangle.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="isVisible"
|
||||
class="pointer-events-none absolute border border-blue-400 bg-blue-500/20"
|
||||
:style="rectangleStyle"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRafFn } from '@vueuse/core'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
|
||||
const canvasStore = useCanvasStore()
|
||||
|
||||
const selectionRect = ref<{
|
||||
x: number
|
||||
y: number
|
||||
w: number
|
||||
h: number
|
||||
} | null>(null)
|
||||
|
||||
useRafFn(() => {
|
||||
const canvas = canvasStore.canvas
|
||||
if (!canvas) {
|
||||
selectionRect.value = null
|
||||
return
|
||||
}
|
||||
|
||||
const { pointer, dragging_rectangle } = canvas
|
||||
|
||||
if (dragging_rectangle && pointer.eDown && pointer.eMove) {
|
||||
const x = pointer.eDown.safeOffsetX
|
||||
const y = pointer.eDown.safeOffsetY
|
||||
const w = pointer.eMove.safeOffsetX - x
|
||||
const h = pointer.eMove.safeOffsetY - y
|
||||
|
||||
selectionRect.value = { x, y, w, h }
|
||||
} else {
|
||||
selectionRect.value = null
|
||||
}
|
||||
})
|
||||
|
||||
const isVisible = computed(() => selectionRect.value !== null)
|
||||
|
||||
const rectangleStyle = computed(() => {
|
||||
const rect = selectionRect.value
|
||||
if (!rect) return {}
|
||||
|
||||
const left = rect.w >= 0 ? rect.x : rect.x + rect.w
|
||||
const top = rect.h >= 0 ? rect.y : rect.y + rect.h
|
||||
const width = Math.abs(rect.w)
|
||||
const height = Math.abs(rect.h)
|
||||
|
||||
return {
|
||||
left: `${left}px`,
|
||||
top: `${top}px`,
|
||||
width: `${width}px`,
|
||||
height: `${height}px`
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -4799,7 +4799,8 @@ export class LGraphCanvas
|
||||
}
|
||||
|
||||
// Area-selection rectangle
|
||||
if (this.dragging_rectangle) {
|
||||
// In Vue nodes mode, selection rectangle is rendered in DOM layer
|
||||
if (this.dragging_rectangle && !LiteGraph.vueNodesMode) {
|
||||
const { eDown, eMove } = this.pointer
|
||||
ctx.strokeStyle = '#FFF'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user