Skip to content

Commit a762517

Browse files
committed
Add limited support for objectPosition property
1 parent 5210513 commit a762517

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
@@ -8,6 +8,7 @@ import overflow from './overflow.js'
88
import { buildXMLString } from '../utils.js'
99
import border, { getBorderClipPath } from './border.js'
1010
import { genClipPath } from './clip-path.js'
11+
import { getPreserveAspectRatio } from './image.js'
1112

1213
export default async function rect(
1314
{
@@ -187,12 +188,10 @@ export default async function rect(
187188
((style.borderBottomWidth as number) || 0) +
188189
((style.paddingBottom as number) || 0)
189190

190-
const preserveAspectRatio =
191-
style.objectFit === 'contain'
192-
? 'xMidYMid'
193-
: style.objectFit === 'cover'
194-
? 'xMidYMid slice'
195-
: 'none'
191+
const preserveAspectRatio = getPreserveAspectRatio(
192+
String(style.objectFit),
193+
String(style.objectPosition)
194+
)
196195

197196
shape += buildXMLString('image', {
198197
x: left + offsetLeft,

test/image.test.tsx

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

393393
expect(toImage(svg, 100)).toMatchImageSnapshot()
394394
})
395+
396+
it('should convert objectFit', async () => {
397+
const svg = await satori(
398+
<div
399+
style={{
400+
width: '100%',
401+
height: '100%',
402+
display: 'flex',
403+
}}
404+
>
405+
<img
406+
width='100%'
407+
height='100%'
408+
src='https://via.placeholder.com/150'
409+
style={{
410+
objectFit: 'cover',
411+
}}
412+
/>
413+
</div>,
414+
{ width: 100, height: 100, fonts }
415+
)
416+
417+
expect(svg).toContain('preserveAspectRatio="xMidYMid slice"')
418+
})
419+
420+
it('should convert objectPosition', async () => {
421+
const svg = await satori(
422+
<div
423+
style={{
424+
width: '100%',
425+
height: '100%',
426+
display: 'flex',
427+
}}
428+
>
429+
<img
430+
width='100%'
431+
height='100%'
432+
src='https://via.placeholder.com/150'
433+
style={{
434+
objectFit: 'cover',
435+
objectPosition: 'right top',
436+
}}
437+
/>
438+
</div>,
439+
{ width: 100, height: 100, fonts }
440+
)
441+
442+
expect(svg).toContain('preserveAspectRatio="xMaxYMin slice"')
443+
})
395444
})
396445

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

0 commit comments

Comments
 (0)