fix(canvas): tune Figma pattern origin

This commit is contained in:
Danila Poyarkov 2026-05-26 21:21:49 +03:00
parent 16e523380b
commit 94dd6cf3aa
4 changed files with 19 additions and 12 deletions

View file

@ -105,9 +105,14 @@ interface PatternTileLayout {
positions: Vector[]
}
function patternAlignmentOffset(alignment: Fill['horizontalAlignment'], gap: number): number {
if (alignment === 'CENTER') return gap / 2
if (alignment === 'END') return gap
function patternAlignmentOffset(
alignment: Fill['horizontalAlignment'],
gap: number,
sourceSize: number,
axis: 'x' | 'y'
): number {
if (alignment === 'CENTER') return axis === 'x' ? -gap / 2 : -sourceSize / 2
if (alignment === 'END') return -gap
return 0
}
@ -120,8 +125,8 @@ export function patternTileLayout(source: SceneNode, fill: Fill): PatternTileLay
const gapY = scaledHeight * spacing.y
const width = scaledWidth + gapX
const height = scaledHeight + gapY
const x = patternAlignmentOffset(fill.horizontalAlignment, gapX)
const y = patternAlignmentOffset(fill.verticalAlignment, gapY)
const x = patternAlignmentOffset(fill.horizontalAlignment, gapX, scaledWidth, 'x')
const y = patternAlignmentOffset(fill.verticalAlignment, gapY, scaledHeight, 'y')
const positions = [{ x, y }]
if (fill.patternTileType === 'HORIZONTAL_HEXAGONAL') {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -42,7 +42,7 @@ describe('canvas pattern fills', () => {
expect(layout).toEqual({
rect: { x: 0, y: 0, width: 50, height: 30 },
scale: 2,
positions: [{ x: 5, y: 10 }]
positions: [{ x: -5, y: -10 }]
})
})

View file

@ -8,13 +8,15 @@
{
"name": "pattern-visible-source-frame",
"nodeId": "296784:2258",
"output": "/tmp/open-pencil-oracles/pattern-visible-source-norm",
"output": "/tmp/open-pencil-oracles/pattern-visible-source-tuned",
"figmaSize": "190x110",
"openPencilSize": "190x110",
"differentPixels": 13026,
"differentPercent": 62.33,
"rmseNormalized": 0.361297,
"finding": "This is the reliable pattern oracle: source and target are copied together and Figma renders the pattern. OpenPencil now resolves the source, but tile origin/spacing still differs from Figma."
"differentPixels": 7180,
"differentPercent": 34.35,
"rmseNormalized": 0.235698,
"previousDifferentPixels": 13026,
"previousDifferentPercent": 62.33,
"finding": "This is the reliable pattern oracle: source and target are copied together and Figma renders the pattern. OpenPencil resolves the source and now uses a closer Figma-like pattern origin, but exact row spacing/tile origin still differs."
},
{
"name": "rich-text-decorations",
@ -61,7 +63,7 @@
}
],
"nextActions": [
"Tune pattern tile origin and spacing against pattern-visible-source-frame.",
"Continue tuning pattern row spacing and tile origin against pattern-visible-source-frame.",
"Use perceptual/color-tolerant image diff for mask comparisons instead of raw absolute-error counts.",
"Tune rich text line metrics before treating underline placement diffs as actionable."
]