test(canvas): summarize pattern oracle deltas

This commit is contained in:
Danila Poyarkov 2026-05-27 14:25:10 +03:00
parent ca775f05c1
commit da537c05a7
3 changed files with 87 additions and 7 deletions

View file

@ -66,16 +66,13 @@ const analysis =
regions.map((region) => {
const figmaRows = summarizeRows(findPatternComponents(figma, minComponentPixels, region))
const oursRows = summarizeRows(findPatternComponents(ours, minComponentPixels, region))
return [
region.name,
{ figma: figmaRows, ours: oursRows, rowDeltas: rowDeltas(figmaRows, oursRows) }
]
return [region.name, analyzeRows(figmaRows, oursRows)]
})
)
: (() => {
const figmaRows = summarizeRows(findPatternComponents(figma, minComponentPixels))
const oursRows = summarizeRows(findPatternComponents(ours, minComponentPixels))
return { figma: figmaRows, ours: oursRows, rowDeltas: rowDeltas(figmaRows, oursRows) }
return analyzeRows(figmaRows, oursRows)
})()
console.log(JSON.stringify(analysis, null, 2))
@ -236,7 +233,36 @@ function summarizeRows(components: Component[]): RowSummary[] {
.toSorted((a, b) => a.y - b.y)
}
function rowDeltas(figmaRows: RowSummary[], oursRows: RowSummary[]) {
function analyzeRows(figmaRows: RowSummary[], oursRows: RowSummary[]) {
const pairedRows = pairedRowDeltas(figmaRows, oursRows)
return {
figma: figmaRows,
ours: oursRows,
pairedRows,
nearestRows: nearestRowDeltas(figmaRows, oursRows),
summary: rowDeltaSummary(pairedRows, figmaRows.length, oursRows.length)
}
}
function pairedRowDeltas(figmaRows: RowSummary[], oursRows: RowSummary[]) {
const count = Math.min(figmaRows.length, oursRows.length)
return Array.from({ length: count }, (_, index) => {
const figmaRow = figmaRows[index]
const oursRow = oursRows[index]
return {
index,
figmaY: figmaRow?.y ?? null,
oursY: oursRow?.y ?? null,
deltaY: figmaRow && oursRow ? Number((oursRow.y - figmaRow.y).toFixed(2)) : null,
figmaFirstX: figmaRow?.firstX ?? null,
oursFirstX: oursRow?.firstX ?? null,
deltaFirstX:
figmaRow && oursRow ? Number((oursRow.firstX - figmaRow.firstX).toFixed(2)) : null
}
})
}
function nearestRowDeltas(figmaRows: RowSummary[], oursRows: RowSummary[]) {
return figmaRows.map((figmaRow) => {
const nearest = oursRows.toSorted(
(a, b) => Math.abs(a.y - figmaRow.y) - Math.abs(b.y - figmaRow.y)
@ -251,3 +277,21 @@ function rowDeltas(figmaRows: RowSummary[], oursRows: RowSummary[]) {
}
})
}
function rowDeltaSummary(
rows: ReturnType<typeof pairedRowDeltas>,
figmaRowCount: number,
openPencilRowCount: number
) {
const valid = rows.filter((row) => row.deltaY !== null && row.deltaFirstX !== null)
if (valid.length === 0) return null
const avgDeltaY = valid.reduce((sum, row) => sum + (row.deltaY ?? 0), 0) / valid.length
const avgDeltaFirstX = valid.reduce((sum, row) => sum + (row.deltaFirstX ?? 0), 0) / valid.length
return {
pairedRowCount: valid.length,
avgDeltaY: Number(avgDeltaY.toFixed(2)),
avgDeltaFirstX: Number(avgDeltaFirstX.toFixed(2)),
missingOpenPencilRows: Math.max(0, figmaRowCount - openPencilRowCount),
extraOpenPencilRows: Math.max(0, openPencilRowCount - figmaRowCount)
}
}

View file

@ -36,6 +36,16 @@ interface PaintOracle {
source: { id: string; visible: boolean }
targets: Array<{ alignment: string; fills: PatternOracleFill[] }>
metrics: { rmseNormalized: number; fuzzDifferentPixels: number }
analysis: Record<
string,
{
pairedRowCount: number
avgDeltaY: number
avgDeltaFirstX: number
missingOpenPencilRows: number
extraOpenPencilRows: number
}
>
}
effects: {
noise: { results: Record<string, EffectOracleResult> }
@ -83,6 +93,9 @@ describe('Figma pattern/noise/custom paint oracle availability', () => {
}
expect(alignment.metrics.rmseNormalized).toBeCloseTo(0.246422)
expect(alignment.metrics.fuzzDifferentPixels).toBe(22209)
expect(alignment.analysis.START).toMatchObject({ avgDeltaY: 0, avgDeltaFirstX: 0 })
expect(alignment.analysis.CENTER).toMatchObject({ avgDeltaY: 3, avgDeltaFirstX: -0.5 })
expect(alignment.analysis.END).toMatchObject({ avgDeltaY: -6.67, avgDeltaFirstX: -0.5 })
})
test('records that noise and custom paint payloads are still blocked on Figma-authored samples', () => {

View file

@ -287,6 +287,29 @@
"fuzzDifferentPercent": 30.51,
"rmseNormalized": 0.246422
},
"note": "Captures START/CENTER/END pattern alignment in one frame with a visible source node. START matches current OpenPencil row origin closely; CENTER and END show remaining Figma origin differences."
"note": "Captures START/CENTER/END pattern alignment in one frame with a visible source node. START matches current OpenPencil row origin closely; CENTER and END show remaining Figma origin differences.",
"analysis": {
"START": {
"pairedRowCount": 6,
"avgDeltaY": 0,
"avgDeltaFirstX": 0,
"missingOpenPencilRows": 0,
"extraOpenPencilRows": 0
},
"CENTER": {
"pairedRowCount": 6,
"avgDeltaY": 3,
"avgDeltaFirstX": -0.5,
"missingOpenPencilRows": 1,
"extraOpenPencilRows": 0
},
"END": {
"pairedRowCount": 6,
"avgDeltaY": -6.67,
"avgDeltaFirstX": -0.5,
"missingOpenPencilRows": 0,
"extraOpenPencilRows": 0
}
}
}
}