react-native-morph-card 0.1.15 → 0.2.0

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.
@@ -738,7 +738,7 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
738
738
  this@MorphCardSourceView.alpha = 1f
739
739
 
740
740
  transferSnapshotToTarget(decorView, wrapper, targetView,
741
- targetWidthPx, targetHeightPx, targetCornerRadiusPx, 200L)
741
+ targetWidthPx, targetHeightPx, targetCornerRadiusPx)
742
742
 
743
743
  promise.resolve(true)
744
744
  }
@@ -759,8 +759,7 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
759
759
  targetView: View?,
760
760
  targetWidthPx: Float,
761
761
  targetHeightPx: Float,
762
- cornerRadius: Float,
763
- fadeDuration: Long = 100
762
+ cornerRadius: Float
764
763
  ) {
765
764
  val target = targetView as? MorphCardTargetView
766
765
  if (target == null) {
@@ -803,19 +802,9 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
803
802
  Log.d(TAG, "transferSnapshot: handed snapshot to MorphCardTargetView")
804
803
  }
805
804
 
806
- val fadeOut = ValueAnimator.ofFloat(1f, 0f)
807
- fadeOut.duration = fadeDuration
808
- fadeOut.addUpdateListener { anim ->
809
- overlay.alpha = anim.animatedValue as Float
810
- }
811
- fadeOut.addListener(object : android.animation.AnimatorListenerAdapter() {
812
- override fun onAnimationEnd(animation: android.animation.Animator) {
813
- decorView.removeView(overlay)
814
- overlayContainer = null
815
- Log.d(TAG, "transferSnapshot: overlay fade-out complete")
816
- }
817
- })
818
- fadeOut.start()
805
+ decorView.removeView(overlay)
806
+ overlayContainer = null
807
+ Log.d(TAG, "transferSnapshot: overlay removed")
819
808
  }
820
809
 
821
810
  // ══════════════════════════════════════════════════════════════
@@ -128,25 +128,54 @@ static CGRect imageFrameForScaleMode(UIViewContentMode mode,
128
128
  #pragma mark - Snapshot helper
129
129
 
130
130
  - (UIImage *)captureSnapshot {
131
- // Render children directly into a fresh context so the snapshot
132
- // captures full rectangular content without the source view's
133
- // cornerRadius clipping. No on-screen flash since we never
134
- // modify visible properties.
131
+ // Temporarily disable clipsToBounds + cornerRadius on all descendants so we
132
+ // capture full rectangular content (like iOS does for the source layer itself).
133
+ // This mirrors the Android fix that disables Fresco's RoundingParams.
134
+ NSMutableArray<NSDictionary *> *clippedViews = [NSMutableArray array];
135
+ __block void (^prepareView)(UIView *);
136
+ prepareView = ^(UIView *view) {
137
+ if (view.clipsToBounds && view.layer.cornerRadius > 0) {
138
+ [clippedViews addObject:@{
139
+ @"view": view,
140
+ @"radius": @(view.layer.cornerRadius)
141
+ }];
142
+ view.layer.cornerRadius = 0;
143
+ view.clipsToBounds = NO;
144
+ }
145
+ for (UIView *child in view.subviews) {
146
+ prepareView(child);
147
+ }
148
+ };
149
+ for (UIView *child in self.subviews) {
150
+ prepareView(child);
151
+ }
152
+
135
153
  UIGraphicsImageRendererFormat *format =
136
154
  [UIGraphicsImageRendererFormat defaultFormat];
137
155
  format.opaque = NO;
138
156
  CGSize size = self.bounds.size;
139
157
  UIGraphicsImageRenderer *renderer =
140
158
  [[UIGraphicsImageRenderer alloc] initWithSize:size format:format];
141
- return [renderer imageWithActions:^(UIGraphicsImageRendererContext *ctx) {
142
- for (UIView *child in self.subviews) {
143
- CGContextSaveGState(ctx.CGContext);
144
- CGContextTranslateCTM(ctx.CGContext, child.frame.origin.x, child.frame.origin.y);
145
- [child drawViewHierarchyInRect:(CGRect){CGPointZero, child.frame.size}
146
- afterScreenUpdates:NO];
147
- CGContextRestoreGState(ctx.CGContext);
148
- }
149
- }];
159
+ UIImage *image =
160
+ [renderer imageWithActions:^(UIGraphicsImageRendererContext *ctx) {
161
+ for (UIView *child in self.subviews) {
162
+ CGContextSaveGState(ctx.CGContext);
163
+ CGContextTranslateCTM(ctx.CGContext, child.frame.origin.x,
164
+ child.frame.origin.y);
165
+ [child drawViewHierarchyInRect:(CGRect){CGPointZero, child.frame.size}
166
+ afterScreenUpdates:NO];
167
+ CGContextRestoreGState(ctx.CGContext);
168
+ }
169
+ }];
170
+
171
+ // Restore clipping
172
+ for (NSDictionary *entry in clippedViews) {
173
+ UIView *view = entry[@"view"];
174
+ view.layer.cornerRadius = [entry[@"radius"] floatValue];
175
+ view.clipsToBounds = YES;
176
+ }
177
+
178
+ return image;
150
179
  }
151
180
 
152
181
  #pragma mark - Expand
@@ -258,9 +287,7 @@ static CGRect imageFrameForScaleMode(UIViewContentMode mode,
258
287
  UIView *ts = self->_targetScreenContainer;
259
288
  if (ts) {
260
289
  [UIView animateWithDuration:dur * 0.5
261
- animations:^{
262
- ts.alpha = 1;
263
- }
290
+ animations:^{ ts.alpha = 1; }
264
291
  completion:nil];
265
292
  }
266
293
  });
@@ -284,14 +311,8 @@ static CGRect imageFrameForScaleMode(UIViewContentMode mode,
284
311
  self.alpha = 1;
285
312
  UIView *ts = self->_targetScreenContainer;
286
313
  if (ts) { ts.alpha = 1; }
287
- [UIView animateWithDuration:0.2
288
- animations:^{
289
- wrapper.alpha = 0;
290
- }
291
- completion:^(BOOL finished) {
292
- [wrapper removeFromSuperview];
293
- self->_wrapperView = nil;
294
- }];
314
+ [wrapper removeFromSuperview];
315
+ self->_wrapperView = nil;
295
316
  resolve(@(YES));
296
317
  }];
297
318
 
@@ -345,9 +366,7 @@ static CGRect imageFrameForScaleMode(UIViewContentMode mode,
345
366
  UIView *ts = self->_targetScreenContainer;
346
367
  if (ts) {
347
368
  [UIView animateWithDuration:dur * 0.5
348
- animations:^{
349
- ts.alpha = 1;
350
- }
369
+ animations:^{ ts.alpha = 1; }
351
370
  completion:nil];
352
371
  }
353
372
  });
@@ -365,15 +384,9 @@ static CGRect imageFrameForScaleMode(UIViewContentMode mode,
365
384
  self.alpha = 1;
366
385
  UIView *ts = self->_targetScreenContainer;
367
386
  if (ts) { ts.alpha = 1; }
368
- [UIView animateWithDuration:0.2
369
- animations:^{
370
- container.alpha = 0;
371
- }
372
- completion:^(BOOL finished) {
373
- [container removeFromSuperview];
374
- self->_wrapperView = nil;
375
- self->_snapshot = nil;
376
- }];
387
+ [container removeFromSuperview];
388
+ self->_wrapperView = nil;
389
+ self->_snapshot = nil;
377
390
  resolve(@(YES));
378
391
  }];
379
392
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-morph-card",
3
- "version": "0.1.15",
3
+ "version": "0.2.0",
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",