react-native-skia icon indicating copy to clipboard operation
react-native-skia copied to clipboard

BoxShadow not working with rounded rectangle on Android

Open rob-johansen opened this issue 1 year ago • 4 comments

Description

I'm using <Box> with rrect() and <BoxShadow>, and the shadow doesn't seem to be masked/clipped properly on Android—at least not on my Google Pixel 5. It seems fine in the iOS Simulator (so far I've only tried with an iPhone 11 running iOS 16.4).

Version

Release 0.1.197 beta

Steps to reproduce

  1. Render a <Box> with rrect() and <BoxShadow>.
  2. Observe an a Google Pixel 5 (hopefully it's not specific to this particular phone model).
  3. Now render just the <Box> and observe that it's rounded on Android, as expected.

Snack, code example, screenshot, or link to a repository

Here's my simple code example. In case it matters, I happen to be rendering dynamic box sizes, so I'm including the width and height calculated for Android and iOS (the rest of the code is identical), followed by screenshots.

Android

const size = 46.84090909090909

<Box
  box={rrect(rect(0, 0, size, size), 5, 5)}
  color="#eeece9"
>
  <BoxShadow dx={4} dy={4} blur={4} color="#d0cecb" inner />
</Box>

android

iOS

const size = 49.5

<Box
  box={rrect(rect(0, 0, size, size), 5, 5)}
  color="#eeece9"
>
  <BoxShadow dx={4} dy={4} blur={4} color="#d0cecb" inner />
</Box>
ios

rob-johansen avatar Jul 25 '23 02:07 rob-johansen

We have some tests for this on Android and iOS: https://github.com/Shopify/react-native-skia/blob/main/package/src/renderer/tests/e2e/Box.spec.tsx#L16 It would be good to see if these work on your Android device. Another thing that would be really interesting to test is if you can achieve the desired result using the RoundedRect component and Shadow: https://shopify.github.io/react-native-skia/docs/shapes/polygons/#roundedrect https://shopify.github.io/react-native-skia/docs/image-filters/shadows/#inner-shadow

These are also somewhat well tested.

wcandillon avatar Jul 25 '23 04:07 wcandillon

We have some tests for this on Android and iOS: https://github.com/Shopify/react-native-skia/blob/main/package/src/renderer/tests/e2e/Box.spec.tsx#L16 It would be good to see if these work on your Android device.

Thanks for your response.

How do I run the tests against my Android device? I plugged it in via USB and ran yarn test from the package directory; however, I don't think it was testing my device (sorry if this is obvious).

Another thing that would be really interesting to test is if you can achieve the desired result using the RoundedRect component and Shadow

Indeed this renders the rounded rectangle and shadow correctly, but then performance is a problem because I need to draw a 15x15 grid (225 rounded rectangles).

rob-johansen avatar Jul 27 '23 01:07 rob-johansen

Are all rectangles of the same size? If yes it may be worth it to just draw it once and display its bitmap 224 times. I may recommend a couple of approaches there:

  • If there is a bug in Box we are still interested to find/fix it.
  • Box is using a trick to do fast inner shadows (like CSS does with box-shadow vs shadow filter) using drrect: https://shopify.github.io/react-native-skia/docs/shapes/polygons/#diffrect. You may have better luck using this component directly (also by looking at https://github.com/Shopify/react-native-skia/blob/main/package/src/dom/nodes/drawings/Box.ts).
  • You may need to use one box as a sprite anyways (depending on your use-case).

wcandillon avatar Jul 27 '23 06:07 wcandillon

Thanks, I'll consider these options.

rob-johansen avatar Jul 28 '23 22:07 rob-johansen