Skip to content

Commit 4a7d0bc

Browse files
authored
feat: added obj fit to image (#703)
1 parent 50a7948 commit 4a7d0bc

13 files changed

+238
-2
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ Satori uses the same Flexbox [layout engine](https://yogalayout.com) as React Na
228228
<td></td>
229229
</tr>
230230

231+
<tr>
232+
<td colspan="2"><code>objectPosition</code></td>
233+
<td>Support keywords: <code>top</code>, <code>bottom</code>, <code>left</code>, <code>right</code>, <code>center</code>, and combinations like <code>top left</code>. Defaults to <code>center</code>.</td>
234+
<td></td>
235+
</tr>
236+
231237
<tr>
232238
<td colspan="2"><code>opacity</code></td>
233239
<td>Supported</td>

src/builder/rect.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,51 @@ export default async function rect(
203203
((style.borderBottomWidth as number) || 0) +
204204
((style.paddingBottom as number) || 0)
205205

206+
let xAlign = 'Mid'
207+
let yAlign = 'Mid'
208+
const position = (style.objectPosition || 'center')
209+
.toString()
210+
.trim()
211+
.toLowerCase()
212+
const parts = position.split(/\s+/)
213+
if (parts.length === 1) {
214+
switch (parts[0]) {
215+
case 'left':
216+
xAlign = 'Min'
217+
yAlign = 'Mid'
218+
break
219+
case 'right':
220+
xAlign = 'Max'
221+
yAlign = 'Mid'
222+
break
223+
case 'top':
224+
xAlign = 'Mid'
225+
yAlign = 'Min'
226+
break
227+
case 'bottom':
228+
xAlign = 'Mid'
229+
yAlign = 'Max'
230+
break
231+
case 'center':
232+
xAlign = 'Mid'
233+
yAlign = 'Mid'
234+
break
235+
}
236+
} else if (parts.length === 2) {
237+
for (const part of parts) {
238+
if (part === 'left') xAlign = 'Min'
239+
else if (part === 'right') xAlign = 'Max'
240+
else if (part === 'center') xAlign = 'Mid'
241+
else if (part === 'top') yAlign = 'Min'
242+
else if (part === 'bottom') yAlign = 'Max'
243+
}
244+
}
245+
const alignment = `x${xAlign}Y${yAlign}`
206246
const preserveAspectRatio =
207247
style.objectFit === 'contain'
208-
? 'xMidYMid'
248+
? alignment
209249
: style.objectFit === 'cover'
210-
? 'xMidYMid slice'
250+
? `${alignment} slice`
211251
: 'none'
212252

213253
if (style.transform) {
10.3 KB
Loading
14.5 KB
Loading
10.3 KB
Loading
14.5 KB
Loading
14.5 KB
Loading
13.7 KB
Loading
13.3 KB
Loading
14.5 KB
Loading

0 commit comments

Comments
 (0)