fix(canvas): orient linear gradients like Figma

This commit is contained in:
Danila Poyarkov 2026-05-18 03:21:16 +03:00
parent f365ccf23b
commit a0ba8bda3a
2 changed files with 35 additions and 4 deletions

View file

@ -104,6 +104,17 @@ function makeGradientLocalMatrix(
])
}
export function linearGradientEndpoints(
width: number,
height: number,
transform: NonNullable<Fill['gradientTransform']>
) {
return {
start: { x: (transform.m00 + transform.m02) * width, y: (transform.m10 + transform.m12) * height },
end: { x: transform.m02 * width, y: transform.m12 * height }
}
}
export function applyGradientFill(
r: SkiaRenderer,
fill: Fill,
@ -135,10 +146,11 @@ export function applyGradientFill(
const h = node.height
if (fill.type === 'GRADIENT_LINEAR') {
const startX = t.m02 * w
const startY = t.m12 * h
const endX = (t.m00 + t.m02) * w
const endY = (t.m10 + t.m12) * h
const { start, end } = linearGradientEndpoints(w, h, t)
const startX = start.x
const startY = start.y
const endX = end.x
const endY = end.y
const shader = r.ck.Shader.MakeLinearGradient(
[startX, startY],
[endX, endY],

View file

@ -0,0 +1,19 @@
import { describe, expect, test } from 'bun:test'
import { linearGradientEndpoints } from '#core/canvas/fills'
describe('canvas gradients', () => {
test('maps figma linear gradient start color to transformed x-axis endpoint', () => {
const endpoints = linearGradientEndpoints(188, 270, {
m00: 0,
m01: 1,
m02: 0,
m10: -1,
m11: 0,
m12: 1
})
expect(endpoints.start).toEqual({ x: 0, y: 0 })
expect(endpoints.end).toEqual({ x: 0, y: 270 })
})
})