Files
ComfyUI_frontend/src/extensions/core/selectionBorder.ts
Simula_r 84e7102f70 Fix/selection toolbox reflow (#5158)
* fix: layout perf issue

* feat: skip a whole host of transform issues created by the SelectionOverlay and instead allowing the canvas to render the overlay and then injecting props to the SelecitonToolbox itself

* refactor: removed unused files/functionality

* refactor: removed unused types

* fix: z index issue

* fix: PR feedback

* fix: PR feedback and more perf improvements

* Update test expectations [skip ci]

---------

Co-authored-by: github-actions <github-actions@github.com>
2025-08-22 12:36:20 -07:00

71 lines
1.8 KiB
TypeScript

import { type LGraphCanvas, createBounds } from '@/lib/litegraph/src/litegraph'
import { app } from '@/scripts/app'
/**
* Draws a dashed border around selected items that maintains constant pixel size
* regardless of zoom level, similar to the DOM selection overlay.
*/
function drawSelectionBorder(
ctx: CanvasRenderingContext2D,
canvas: LGraphCanvas
) {
const selectedItems = canvas.selectedItems
// Only draw if multiple items selected
if (selectedItems.size <= 1) return
// Use the same bounds calculation as the toolbox
const bounds = createBounds(selectedItems, 10)
if (!bounds) return
const [x, y, width, height] = bounds
// Save context state
ctx.save()
// Set up dashed line style that doesn't scale with zoom
const borderWidth = 2 / canvas.ds.scale // Constant 2px regardless of zoom
ctx.lineWidth = borderWidth
ctx.strokeStyle =
getComputedStyle(document.documentElement)
.getPropertyValue('--border-color')
.trim() || '#ffffff66'
// Create dash pattern that maintains visual size
const dashSize = 5 / canvas.ds.scale
ctx.setLineDash([dashSize, dashSize])
// Draw the border using the bounds directly
ctx.beginPath()
ctx.roundRect(x, y, width, height, 8 / canvas.ds.scale)
ctx.stroke()
// Restore context
ctx.restore()
}
/**
* Extension that adds a dashed selection border for multiple selected nodes
*/
const ext = {
name: 'Comfy.SelectionBorder',
async init() {
// Hook into the canvas drawing
const originalDrawForeground = app.canvas.onDrawForeground
app.canvas.onDrawForeground = function (
ctx: CanvasRenderingContext2D,
visibleArea: any
) {
// Call original if it exists
originalDrawForeground?.call(this, ctx, visibleArea)
// Draw our selection border
drawSelectionBorder(ctx, app.canvas)
}
}
}
app.registerExtension(ext)