Skip to content

Commit c96ea51

Browse files
fix(android): fall back to BACKGROUND outline provider when borderRadius is not animated
When borderRadius is not in the animated bitmask, use ViewOutlineProvider.BACKGROUND so elevation shadows respect the style borderRadius from the background drawable. Only switch to the custom provider when borderRadius is actively animated.
1 parent 9e04179 commit c96ea51

2 files changed

Lines changed: 20 additions & 9 deletions

File tree

android/src/main/java/com/ease/EaseView.kt

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,16 @@ class EaseView(context: Context) : ReactViewGroup(context) {
252252
cameraDistance = density * density * perspective * CAMERA_DISTANCE_NORMALIZATION_MULTIPLIER
253253
}
254254

255+
// Custom outline provider used when borderRadius is animated.
256+
// Reads _borderRadius dynamically — invalidated on each frame by setAnimateBorderRadius.
257+
private val animatedOutlineProvider = object : ViewOutlineProvider() {
258+
override fun getOutline(view: View, outline: Outline) {
259+
outline.setRoundRect(0, 0, view.width, view.height, _borderRadius)
260+
}
261+
}
262+
255263
init {
256264
applyCameraDistance(1280f)
257-
258-
// ViewOutlineProvider reads _borderRadius dynamically — set once, invalidated on each frame.
259-
outlineProvider = object : ViewOutlineProvider() {
260-
override fun getOutline(view: View, outline: Outline) {
261-
outline.setRoundRect(0, 0, view.width, view.height, _borderRadius)
262-
}
263-
}
264265
}
265266

266267
// --- Hardware layer management ---
@@ -327,6 +328,16 @@ class EaseView(context: Context) : ReactViewGroup(context) {
327328
// Bitmask: which properties are animated. Non-animated = let style handle.
328329
val mask = animatedProperties
329330

331+
// Use custom outline provider only when borderRadius is animated.
332+
// Otherwise fall back to BACKGROUND provider so elevation shadows
333+
// respect the style borderRadius from the background drawable.
334+
val needsCustomOutline = mask and MASK_BORDER_RADIUS != 0
335+
if (needsCustomOutline && outlineProvider !== animatedOutlineProvider) {
336+
outlineProvider = animatedOutlineProvider
337+
} else if (!needsCustomOutline && outlineProvider === animatedOutlineProvider) {
338+
outlineProvider = ViewOutlineProvider.BACKGROUND
339+
}
340+
330341
if (isFirstMount) {
331342
isFirstMount = false
332343

@@ -1005,6 +1016,7 @@ class EaseView(context: Context) : ReactViewGroup(context) {
10051016
setAnimateBorderWidth(0f)
10061017
applyBorderColor(Color.BLACK)
10071018
this.elevation = 0f
1019+
outlineProvider = ViewOutlineProvider.BACKGROUND
10081020

10091021
transformPerspective = 1280f
10101022
isFirstMount = true

example/src/demos/ShadowDemo.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ export function ShadowDemo() {
1818
shadowRadius: 16,
1919
shadowOffset: { width: 0, height: 8 },
2020
elevation: 12,
21-
borderRadius: 16,
2221
}
2322
: {
2423
shadowOpacity: 0,
2524
shadowRadius: 0,
2625
shadowOffset: { width: 0, height: 0 },
2726
elevation: 0,
28-
borderRadius: 16,
2927
}
3028
}
3129
transition={{
@@ -60,6 +58,7 @@ const styles = StyleSheet.create({
6058
box: {
6159
width: 100,
6260
height: 100,
61+
borderRadius: 16,
6362
backgroundColor: '#fff',
6463
shadowColor: '#000',
6564
alignItems: 'center',

0 commit comments

Comments
 (0)