Skip to content

Commit 940de75

Browse files
committed
Add limited support for objectPosition property
1 parent 29fe2e4 commit 940de75

File tree

3 files changed

+90
-6
lines changed

3 files changed

+90
-6
lines changed

src/builder/image.ts

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
export function getPreserveAspectRatio(
2+
objectFit: string,
3+
objectPosition?: string
4+
) {
5+
if (objectFit !== 'contain' && objectFit !== 'cover') {
6+
return 'none'
7+
}
8+
9+
let align = 'xMidYMid'
10+
11+
if (objectPosition) {
12+
const parts = objectPosition.split(' ')
13+
14+
if (parts.length === 2) {
15+
const [x, y] = parts
16+
17+
if (x === 'left') {
18+
align = 'xMin'
19+
} else if (x === 'right') {
20+
align = 'xMax'
21+
} else {
22+
align = 'XMid'
23+
}
24+
25+
if (y === 'top') {
26+
align += 'YMin'
27+
} else if (y === 'bottom') {
28+
align += 'YMax'
29+
} else {
30+
align += 'YMid'
31+
}
32+
}
33+
}
34+
35+
return align + (objectFit === 'cover' ? ' slice' : '')
36+
}

src/builder/rect.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { buildXMLString } from '../utils.js'
99
import border, { getBorderClipPath } from './border.js'
1010
import { genClipPath } from './clip-path.js'
1111
import buildMaskImage from './mask-image.js'
12+
import { getPreserveAspectRatio } from './image.js'
1213

1314
export default async function rect(
1415
{
@@ -200,12 +201,10 @@ export default async function rect(
200201
((style.borderBottomWidth as number) || 0) +
201202
((style.paddingBottom as number) || 0)
202203

203-
const preserveAspectRatio =
204-
style.objectFit === 'contain'
205-
? 'xMidYMid'
206-
: style.objectFit === 'cover'
207-
? 'xMidYMid slice'
208-
: 'none'
204+
const preserveAspectRatio = getPreserveAspectRatio(
205+
String(style.objectFit),
206+
String(style.objectPosition)
207+
)
209208

210209
shape += buildXMLString('image', {
211210
x: left + offsetLeft,

test/image.test.tsx

+49
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,55 @@ describe('Image', () => {
427427

428428
expect(toImage(svg, 100)).toMatchImageSnapshot()
429429
})
430+
431+
it('should convert objectFit', async () => {
432+
const svg = await satori(
433+
<div
434+
style={{
435+
width: '100%',
436+
height: '100%',
437+
display: 'flex',
438+
}}
439+
>
440+
<img
441+
width='100%'
442+
height='100%'
443+
src='https://via.placeholder.com/150'
444+
style={{
445+
objectFit: 'cover',
446+
}}
447+
/>
448+
</div>,
449+
{ width: 100, height: 100, fonts }
450+
)
451+
452+
expect(svg).toContain('preserveAspectRatio="xMidYMid slice"')
453+
})
454+
455+
it('should convert objectPosition', async () => {
456+
const svg = await satori(
457+
<div
458+
style={{
459+
width: '100%',
460+
height: '100%',
461+
display: 'flex',
462+
}}
463+
>
464+
<img
465+
width='100%'
466+
height='100%'
467+
src='https://via.placeholder.com/150'
468+
style={{
469+
objectFit: 'cover',
470+
objectPosition: 'right top',
471+
}}
472+
/>
473+
</div>,
474+
{ width: 100, height: 100, fonts }
475+
)
476+
477+
expect(svg).toContain('preserveAspectRatio="xMaxYMin slice"')
478+
})
430479
})
431480

432481
describe('background-image: url()', () => {

0 commit comments

Comments
 (0)