mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-23 15:59:47 +00:00
feat: add CurveEditor component (#8860)
## Summary Prerequisite for upcoming native color correction nodes (ColorCurves). Reusable curve editor with monotone cubic Hermite interpolation, drag-to-add/move/delete control points, and SVG-based rendering. Includes CurvePoint type, LUT generation utility, and useCurveEditor composable for interaction logic. ## Screenshots (if applicable) https://github.com/user-attachments/assets/948352c7-bdf2-40f9-a8f0-35bc2b2f3202 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8860-feat-add-CurveEditor-component-and-d3-shape-dependency-3076d73d3650817f8421f98e349569d0) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import type { ICurveWidget } from '@/lib/litegraph/src/types/widgets'
|
||||
import type {
|
||||
CurveInputSpec,
|
||||
InputSpec as InputSpecV2
|
||||
} from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import type { ComfyWidgetConstructorV2 } from '@/scripts/widgets'
|
||||
|
||||
export const useCurveWidget = (): ComfyWidgetConstructorV2 => {
|
||||
return (node: LGraphNode, inputSpec: InputSpecV2): ICurveWidget => {
|
||||
const spec = inputSpec as CurveInputSpec
|
||||
const defaultValue = spec.default ?? [
|
||||
[0, 0],
|
||||
[1, 1]
|
||||
]
|
||||
|
||||
const rawWidget = node.addWidget(
|
||||
'curve',
|
||||
spec.name,
|
||||
[...defaultValue],
|
||||
() => {}
|
||||
)
|
||||
|
||||
if (rawWidget.type !== 'curve') {
|
||||
throw new Error(`Unexpected widget type: ${rawWidget.type}`)
|
||||
}
|
||||
|
||||
return rawWidget as ICurveWidget
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,9 @@ const WidgetImageCrop = defineAsyncComponent(
|
||||
const WidgetBoundingBox = defineAsyncComponent(
|
||||
() => import('@/components/boundingbox/WidgetBoundingBox.vue')
|
||||
)
|
||||
const WidgetCurve = defineAsyncComponent(
|
||||
() => import('@/components/curve/WidgetCurve.vue')
|
||||
)
|
||||
|
||||
export const FOR_TESTING = {
|
||||
WidgetButton,
|
||||
@@ -175,6 +178,14 @@ const coreWidgetDefinitions: Array<[string, WidgetDefinition]> = [
|
||||
aliases: ['BOUNDING_BOX'],
|
||||
essential: false
|
||||
}
|
||||
],
|
||||
[
|
||||
'curve',
|
||||
{
|
||||
component: WidgetCurve,
|
||||
aliases: ['CURVE'],
|
||||
essential: false
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -206,7 +217,7 @@ export const shouldRenderAsVue = (widget: Partial<SafeWidgetData>): boolean => {
|
||||
return !widget.options?.canvasOnly && !!widget.type
|
||||
}
|
||||
|
||||
const EXPANDING_TYPES = ['textarea', 'markdown', 'load3D'] as const
|
||||
const EXPANDING_TYPES = ['textarea', 'markdown', 'load3D', 'curve'] as const
|
||||
|
||||
export function shouldExpand(type: string): boolean {
|
||||
const canonicalType = getCanonicalType(type)
|
||||
|
||||
Reference in New Issue
Block a user