SrBrahma / react-native-shadow-2

Cross-platform shadow for React Native. Supports Android, iOS, Web, and Expo
MIT License
674 stars 56 forks source link

SVGs in corners with border radius are not aligned properly #79

Closed Jackman3005 closed 1 year ago

Jackman3005 commented 1 year ago

We have a modal with a border radius of 15px that renders on top of other content. The corners allow a small amount of bleed through of the content below inbetween the edge of the view and the start of the shadow. After digging in it looks like if I adjust the offset value just slightly down for the <Stop/> components in the <RadialGradient/> it appears to resolve the issue. There seems to be a bit of math involved in calculating those at this time, and I'm not really sure how to accomplish this programatically as I could only get it to work by tweaking things in the inspector.

See this image below of an example of the bleed through between the edge of the view and the start of the shadow, the white card in the background comes in strongly.

Screenshot 2023-09-27 at 4 19 38 pm
SrBrahma commented 1 year ago

Is it iOS?

SrBrahma commented 1 year ago

Also, please provide me a reproducible example in Expo Snack

Jackman3005 commented 1 year ago

Web, iOS, and Android. I'll hopefully be able to work on a snack for you soon.

Jackman3005 commented 1 year ago

Hi @SrBrahma I found the time to create a snack that exhibits the issue.

The modal is opened with transparent={true} on top of a view that has a red background. You can clearly see the red leaking through on the edges of the modal before the shadow begins. See accompanying screenshots.

Screenshot 2023-10-04 at 11 33 18 am Screenshot 2023-10-04 at 11 35 56 am

Let me know what you think or if there is another way I can help you out with this.

SrBrahma commented 1 year ago

The thing is that the borderRadius is handled differently by React Native styles and the SVG engine, and that engine depends on the platform.

In that example, you can put the View with the white background as a child of the Shadow component, and change the paintInside to true. This way, any gap caused by the different borderRadiuses will just have the Shadow color filling it; the red won't be visible between the two components.

SrBrahma commented 1 year ago

Also, in your example, you can just simply put that white background color inside the style property of the Shadow instead of having it on the wrapping View, together with the paintInside=true.

Jackman3005 commented 1 year ago

Interesting, when I tried paint inside before I did not expect it to be underneath the background-color. But it does appear to give the result I'm looking for.

It's worth noting that I imagine you should be able to resolve this because the behavior is identical across android,iOS, and web, so I don't think it's just caused by a difference in the internal react-native or web-specific engines. Strangely in our implementation it is identical across iOS/Android/web but in the snack it is not. Possibly caused by some of our nested views in the local implementation. Or potentially something with expo 49, but for some reason there are errors running it on expo 49 in the snack...

I will give your solution a try and see how it works in our environment. Cheers

Jackman3005 commented 1 year ago

The solution you mentioned has worked for us and we've gone ahead with that for now.

I wish there was some way I could have guessed this behavior and come up with the solution on my own. I did try paintInside={true} but saw that it covered the whole of the component and did not expect that setting a background would paint the background on top of the shadow :/

Thanks again for your help. Maybe this would be worth adding to the FAQ section?

SrBrahma commented 1 year ago

I believe the reason it covered the whole component is because the white background you had was caused by the parent component, so the child component is rendered after the parent, that's why the paintInside was on top of the parent's background.

Any idea how to write about that on the README? Either on FAQ or on the paintInside/style props description.