Skip to content

Commit 11575c9

Browse files
authored
fix: background-clip:text should compatible with transform and mask (#639)
1 parent 618d565 commit 11575c9

5 files changed

+110
-3
lines changed

src/builder/rect.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -298,11 +298,13 @@ export default async function rect(
298298
(imageBorderRadius ? imageBorderRadius[0] : '') +
299299
clip +
300300
(opacity !== 1 ? `<g opacity="${opacity}">` : '') +
301-
(style.transform && currentClipPath && maskId
302-
? `<g clip-path="${currentClipPath}" mask="${maskId}">`
301+
(style.transform && (currentClipPath || maskId)
302+
? `<g${currentClipPath ? ` clip-path="${currentClipPath}"` : ''}${
303+
maskId ? ` mask="${maskId}"` : ''
304+
}>`
303305
: '') +
304306
(backgroundShapes || shape) +
305-
(style.transform && currentClipPath && maskId ? '</g>' : '') +
307+
(style.transform && (currentClipPath || maskId) ? '</g>' : '') +
306308
(opacity !== 1 ? `</g>` : '') +
307309
(shadow ? shadow[1] : '') +
308310
extra

test/background-clip.test.tsx

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { it, describe, expect } from 'vitest'
2+
3+
import { initFonts, toImage } from './utils.js'
4+
import satori from '../src/index.js'
5+
6+
describe('backgroundClip', () => {
7+
let fonts
8+
initFonts((f) => (fonts = f))
9+
10+
it('should render background-clip:text', async () => {
11+
const svg = await satori(
12+
<div
13+
style={{
14+
display: 'flex',
15+
fontSize: 30,
16+
flexDirection: 'column',
17+
background: '#ffffff',
18+
}}
19+
>
20+
<div
21+
style={{
22+
backgroundImage: 'linear-gradient(to right, red, green)',
23+
WebkitBackgroundClip: 'text',
24+
backgroundClip: 'text',
25+
color: 'transparent',
26+
}}
27+
>
28+
lynn
29+
</div>
30+
</div>,
31+
{
32+
width: 100,
33+
height: 100,
34+
fonts,
35+
}
36+
)
37+
38+
expect(toImage(svg)).toMatchImageSnapshot()
39+
})
40+
41+
it('should render background-clip:text compatible with transform', async () => {
42+
const svg = await satori(
43+
<div
44+
style={{
45+
display: 'flex',
46+
fontSize: 30,
47+
flexDirection: 'column',
48+
background: '#ffffff',
49+
}}
50+
>
51+
<div
52+
style={{
53+
transform: 'translateX(25px)',
54+
backgroundImage: 'linear-gradient(to right, red, green)',
55+
WebkitBackgroundClip: 'text',
56+
backgroundClip: 'text',
57+
color: 'transparent',
58+
}}
59+
>
60+
lynn
61+
</div>
62+
</div>,
63+
{
64+
width: 100,
65+
height: 100,
66+
fonts,
67+
}
68+
)
69+
70+
expect(toImage(svg)).toMatchImageSnapshot()
71+
})
72+
73+
it('should render background-clip:text compatible with mask', async () => {
74+
const svg = await satori(
75+
<div
76+
style={{
77+
display: 'flex',
78+
fontSize: 30,
79+
flexDirection: 'column',
80+
background: '#ffffff',
81+
}}
82+
>
83+
<div
84+
style={{
85+
transform: 'translateX(25px)',
86+
backgroundImage: 'linear-gradient(to right, red, green)',
87+
WebkitBackgroundClip: 'text',
88+
backgroundClip: 'text',
89+
maskImage: 'linear-gradient(to right, blue, transparent)',
90+
color: 'transparent',
91+
}}
92+
>
93+
lynn
94+
</div>
95+
</div>,
96+
{
97+
width: 100,
98+
height: 100,
99+
fonts,
100+
}
101+
)
102+
103+
expect(toImage(svg)).toMatchImageSnapshot()
104+
})
105+
})

0 commit comments

Comments
 (0)