react-native-morph-card 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,10 @@ import android.graphics.Canvas
7
7
  import android.graphics.Color
8
8
  import android.graphics.Outline
9
9
  import android.graphics.RectF
10
+ import android.graphics.Paint
11
+ import android.graphics.PorterDuff
12
+ import android.graphics.PorterDuffXfermode
13
+ import android.graphics.drawable.BitmapDrawable
10
14
  import android.graphics.drawable.ColorDrawable
11
15
  import android.os.Handler
12
16
  import android.os.Looper
@@ -497,6 +501,23 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
497
501
  // Stop intercepting new screens — animation is taking over
498
502
  removeHierarchyListener()
499
503
 
504
+ // The PixelCopy blocker bitmap contains the source card at its original position.
505
+ // Clear the card area so the card wrapper animates without a duplicate underneath.
506
+ // We keep the blocker in place to prevent the target screen from flashing.
507
+ val blockerImg = wrapper.findViewWithTag<FrameLayout>("morphCardWrapper")?.let { cardW ->
508
+ (0 until wrapper.childCount).map { wrapper.getChildAt(it) }.firstOrNull { it !== cardW }
509
+ } as? ImageView
510
+ if (blockerImg != null) {
511
+ val bmp = (blockerImg.drawable as? BitmapDrawable)?.bitmap
512
+ if (bmp != null) {
513
+ val clearCanvas = Canvas(bmp)
514
+ val clearPaint = Paint()
515
+ clearPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
516
+ clearCanvas.drawRect(cardLeft, cardTop, cardLeft + cardWidth, cardTop + cardHeight, clearPaint)
517
+ blockerImg.invalidate()
518
+ }
519
+ }
520
+
500
521
  // Read target position (now settled after delay)
501
522
  val d = density
502
523
  val targetLoc = if (targetView != null) getLocationInWindow(targetView) else intArrayOf(cardLeft.toInt(), cardTop.toInt())
@@ -565,16 +586,17 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
565
586
  }
566
587
 
567
588
  // Crossfade: at 15% of animation, make target screen VISIBLE with alpha=0
568
- // then fade alpha to 1 over 50% of duration. Also remove the blocker image.
589
+ // then fade alpha to 1 over 50% of duration.
569
590
  val targetScreen = targetScreenContainerRef?.get()
570
591
  val sourceScreen2 = sourceScreenContainerRef?.get()
571
- // Find the blocker image (first child of the full-screen overlay, before the card wrapper)
572
- val blockerView = if (wrapper.childCount > 1) wrapper.getChildAt(0) else null
573
592
  if (targetScreen != null && targetScreen !== sourceScreen2) {
574
593
  mainHandler.postDelayed({
575
- // Remove blocker source screen is visible underneath
576
- if (blockerView != null && blockerView.tag != "morphCardWrapper") {
577
- (blockerView.parent as? ViewGroup)?.removeView(blockerView)
594
+ // Remove the blocker so the target screen can fade in underneath the card wrapper
595
+ val blocker = wrapper.findViewWithTag<FrameLayout>("morphCardWrapper")?.let { cardW ->
596
+ (0 until wrapper.childCount).map { wrapper.getChildAt(it) }.firstOrNull { it !== cardW }
597
+ }
598
+ if (blocker != null) {
599
+ (blocker.parent as? ViewGroup)?.removeView(blocker)
578
600
  }
579
601
  // Switch from INVISIBLE to VISIBLE but with alpha=0
580
602
  targetScreen.alpha = 0f
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-morph-card",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Native card-to-modal morph transition for React Native. iOS App Store-style expand animation.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",