@@ -15,6 +15,10 @@ import androidx.dynamicanimation.animation.SpringAnimation
1515import androidx.dynamicanimation.animation.SpringForce
1616import com.facebook.react.bridge.ReadableMap
1717import com.facebook.react.uimanager.BackgroundStyleApplicator
18+ import com.facebook.react.uimanager.LengthPercentage
19+ import com.facebook.react.uimanager.LengthPercentageType
20+ import com.facebook.react.uimanager.PixelUtil
21+ import com.facebook.react.uimanager.style.BorderRadiusProp
1822import com.facebook.react.uimanager.style.LogicalEdge
1923import com.facebook.react.views.view.ReactViewGroup
2024import kotlin.math.sqrt
@@ -160,6 +164,12 @@ class EaseView(context: Context) : ReactViewGroup(context) {
160164 clipToOutline = false
161165 }
162166 invalidateOutline()
167+ // Sync border drawable so borders follow the animated corner radius.
168+ // Value is in pixels; convert back to DIPs for BackgroundStyleApplicator.
169+ val dip = PixelUtil .toDIPFromPixel(value)
170+ BackgroundStyleApplicator .setBorderRadius(
171+ this , BorderRadiusProp .BORDER_RADIUS ,
172+ LengthPercentage (dip, LengthPercentageType .POINT ))
163173 }
164174 }
165175
@@ -246,15 +256,16 @@ class EaseView(context: Context) : ReactViewGroup(context) {
246256 cameraDistance = density * density * perspective * CAMERA_DISTANCE_NORMALIZATION_MULTIPLIER
247257 }
248258
259+ // Custom outline provider used when borderRadius is animated.
260+ // Reads _borderRadius dynamically — invalidated on each frame by setAnimateBorderRadius.
261+ private val animatedOutlineProvider = object : ViewOutlineProvider () {
262+ override fun getOutline (view : View , outline : Outline ) {
263+ outline.setRoundRect(0 , 0 , view.width, view.height, _borderRadius )
264+ }
265+ }
266+
249267 init {
250268 applyCameraDistance(1280f )
251-
252- // ViewOutlineProvider reads _borderRadius dynamically — set once, invalidated on each frame.
253- outlineProvider = object : ViewOutlineProvider () {
254- override fun getOutline (view : View , outline : Outline ) {
255- outline.setRoundRect(0 , 0 , view.width, view.height, _borderRadius )
256- }
257- }
258269 }
259270
260271 // --- Hardware layer management ---
@@ -320,6 +331,16 @@ class EaseView(context: Context) : ReactViewGroup(context) {
320331 // Bitmask: which properties are animated. Non-animated = let style handle.
321332 val mask = animatedProperties
322333
334+ // Use custom outline provider only when borderRadius is animated.
335+ // Otherwise fall back to BACKGROUND provider so elevation shadows
336+ // respect the style borderRadius from the background drawable.
337+ val needsCustomOutline = mask and MASK_BORDER_RADIUS != 0
338+ if (needsCustomOutline && outlineProvider != = animatedOutlineProvider) {
339+ outlineProvider = animatedOutlineProvider
340+ } else if (! needsCustomOutline && outlineProvider == = animatedOutlineProvider) {
341+ outlineProvider = ViewOutlineProvider .BACKGROUND
342+ }
343+
323344 if (isFirstMount) {
324345 isFirstMount = false
325346
@@ -974,6 +995,7 @@ class EaseView(context: Context) : ReactViewGroup(context) {
974995 applyBackgroundColor(Color .TRANSPARENT )
975996 setAnimateBorderWidth(0f )
976997 applyBorderColor(Color .BLACK )
998+ outlineProvider = ViewOutlineProvider .BACKGROUND
977999
9781000 transformPerspective = 1280f
9791001 isFirstMount = true
0 commit comments