Compare commits

..

1 Commits

Author SHA1 Message Date
CodeRabbit Fixer
c1969be7a8 fix: Optimize SVG coordinate transform during CurveEditor drag operations (#9113)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 18:36:58 +01:00
4 changed files with 22 additions and 27 deletions

View File

@@ -51,17 +51,6 @@ export function createMonotoneInterpolator(
}
}
const segCount = n - 1
const segDx = new Float64Array(segCount)
const segM0dx = new Float64Array(segCount)
const segM1dx = new Float64Array(segCount)
for (let i = 0; i < segCount; i++) {
const dx = xs[i + 1] - xs[i]
segDx[i] = dx
segM0dx[i] = slopes[i] * dx
segM1dx[i] = slopes[i + 1] * dx
}
return (x: number): number => {
if (x <= xs[0]) return ys[0]
if (x >= xs[n - 1]) return ys[n - 1]
@@ -74,7 +63,7 @@ export function createMonotoneInterpolator(
else hi = mid
}
const dx = segDx[lo]
const dx = xs[hi] - xs[lo]
if (dx === 0) return ys[lo]
const t = (x - xs[lo]) / dx
@@ -86,7 +75,12 @@ export function createMonotoneInterpolator(
const h01 = -2 * t3 + 3 * t2
const h11 = t3 - t2
return h00 * ys[lo] + h10 * segM0dx[lo] + h01 * ys[hi] + h11 * segM1dx[lo]
return (
h00 * ys[lo] +
h10 * dx * slopes[lo] +
h01 * ys[hi] +
h11 * dx * slopes[hi]
)
}
}

View File

@@ -12,6 +12,7 @@ interface UseCurveEditorOptions {
export function useCurveEditor({ svgRef, modelValue }: UseCurveEditorOptions) {
const dragIndex = ref(-1)
let cleanupDrag: (() => void) | null = null
let cachedInverseCTM: DOMMatrix | null = null
const curvePath = computed(() => {
const points = modelValue.value
@@ -31,16 +32,14 @@ export function useCurveEditor({ svgRef, modelValue }: UseCurveEditorOptions) {
return parts.join('')
})
function svgCoords(e: PointerEvent): [number, number] {
const svg = svgRef.value
if (!svg) return [0, 0]
function svgCoords(
e: PointerEvent,
inverseCTM?: DOMMatrix | null
): [number, number] {
const inv = inverseCTM ?? svgRef.value?.getScreenCTM()?.inverse()
if (!inv) return [0, 0]
const ctm = svg.getScreenCTM()
if (!ctm) return [0, 0]
const svgPt = new DOMPoint(e.clientX, e.clientY).matrixTransform(
ctm.inverse()
)
const svgPt = new DOMPoint(e.clientX, e.clientY).matrixTransform(inv)
return [
Math.max(0, Math.min(1, svgPt.x)),
Math.max(0, Math.min(1, 1 - svgPt.y))
@@ -100,11 +99,12 @@ export function useCurveEditor({ svgRef, modelValue }: UseCurveEditorOptions) {
const svg = svgRef.value
if (!svg) return
cachedInverseCTM = svg.getScreenCTM()?.inverse() ?? null
svg.setPointerCapture(e.pointerId)
const onMove = (ev: PointerEvent) => {
if (dragIndex.value < 0) return
const [x, y] = svgCoords(ev)
const [x, y] = svgCoords(ev, cachedInverseCTM)
const movedPoint: CurvePoint = [x, y]
const newPoints = [...modelValue.value]
newPoints[dragIndex.value] = movedPoint
@@ -116,6 +116,7 @@ export function useCurveEditor({ svgRef, modelValue }: UseCurveEditorOptions) {
const endDrag = () => {
if (dragIndex.value < 0) return
dragIndex.value = -1
cachedInverseCTM = null
svg.removeEventListener('pointermove', onMove)
svg.removeEventListener('pointerup', endDrag)
svg.removeEventListener('lostpointercapture', endDrag)

View File

@@ -189,10 +189,11 @@ export function useWorkflowActionsMenu(
addItem({
id: 'share',
label: t('breadcrumbsMenu.share'),
label: t('menuLabels.Share'),
icon: 'icon-[comfy--send]',
command: async () => {},
visible: false
disabled: true,
visible: isRoot
})
addItem({

View File

@@ -2604,8 +2604,7 @@
"deleteWorkflow": "Delete Workflow",
"deleteBlueprint": "Delete Blueprint",
"enterNewName": "Enter new name",
"missingNodesWarning": "Workflow contains unsupported nodes (highlighted red).",
"share": "Share"
"missingNodesWarning": "Workflow contains unsupported nodes (highlighted red)."
},
"shortcuts": {
"shortcuts": "Shortcuts",