react-native-smooth-clip-view 0.2.5 → 0.2.7
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.
- package/README.md +68 -26
- package/android/CMakeLists.txt +0 -1
- package/android/build.gradle +15 -0
- package/android/src/main/cpp/SmoothClipAndroid.h +12 -8
- package/android/src/main/cpp/SmoothClipBindings.cpp +39 -15
- package/android/src/main/cpp/SmoothClipRegistry.cpp +288 -285
- package/android/src/main/java/com/smoothclipview/ClipGeometryNormalizer.kt +61 -11
- package/android/src/main/java/com/smoothclipview/SmoothClipBindings.kt +28 -4
- package/android/src/main/java/com/smoothclipview/SmoothClipModule.kt +1 -0
- package/android/src/main/java/com/smoothclipview/SmoothClipView.kt +180 -42
- package/android/src/main/java/com/smoothclipview/SmoothClipViewManager.kt +1 -0
- package/cpp/SmoothClipAnimationCurve.h +560 -0
- package/cpp/SmoothClipAnimationId.h +32 -0
- package/cpp/SmoothClipRegistry.h +11 -1
- package/cpp/SmoothClipVelocityTracker.h +30 -10
- package/ios/SmoothClipRegistry.mm +398 -150
- package/ios/SmoothClipTurboModule.cpp +4 -2
- package/ios/SmoothClipTurboModule.h +2 -1
- package/ios/SmoothClipView.mm +85 -140
- package/ios/SmoothClipViewRegistry.h +4 -1
- package/lib/module/NativeSmoothClipModule.js.map +1 -1
- package/lib/module/driverState.js +8 -0
- package/lib/module/driverState.js.map +1 -1
- package/lib/module/drivers.native.js +122 -32
- package/lib/module/drivers.native.js.map +1 -1
- package/lib/module/reactRequests.js +9 -3
- package/lib/module/reactRequests.js.map +1 -1
- package/lib/typescript/src/NativeSmoothClipModule.d.ts +1 -1
- package/lib/typescript/src/NativeSmoothClipModule.d.ts.map +1 -1
- package/lib/typescript/src/driverState.d.ts.map +1 -1
- package/lib/typescript/src/driverTypes.d.ts +3 -2
- package/lib/typescript/src/driverTypes.d.ts.map +1 -1
- package/lib/typescript/src/drivers.native.d.ts.map +1 -1
- package/lib/typescript/src/reactRequests.d.ts +3 -1
- package/lib/typescript/src/reactRequests.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/NativeSmoothClipModule.ts +2 -1
- package/src/driverState.ts +8 -0
- package/src/driverTypes.ts +3 -2
- package/src/drivers.native.ts +160 -29
- package/src/reactRequests.ts +14 -2
|
@@ -75,12 +75,14 @@ void SmoothClipTurboModule::setClipPresentation(
|
|
|
75
75
|
double radius,
|
|
76
76
|
double contentTranslateX,
|
|
77
77
|
double contentTranslateY,
|
|
78
|
-
bool takeOwnership
|
|
78
|
+
bool takeOwnership,
|
|
79
|
+
bool overridePendingAnimation) {
|
|
79
80
|
const smoothclip::Presentation presentation{
|
|
80
81
|
{x, y, width, height, radius}, contentTranslateX, contentTranslateY};
|
|
81
82
|
if (validDriverId(driverId) && finitePresentation(presentation)) {
|
|
82
83
|
smoothclip::setPresentation(
|
|
83
|
-
static_cast<uint64_t>(driverId), presentation, takeOwnership
|
|
84
|
+
static_cast<uint64_t>(driverId), presentation, takeOwnership,
|
|
85
|
+
overridePendingAnimation);
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
|
|
@@ -49,7 +49,8 @@ class SmoothClipTurboModule final
|
|
|
49
49
|
double radius,
|
|
50
50
|
double contentTranslateX,
|
|
51
51
|
double contentTranslateY,
|
|
52
|
-
bool takeOwnership
|
|
52
|
+
bool takeOwnership,
|
|
53
|
+
bool overridePendingAnimation);
|
|
53
54
|
jsi::Array beginInteraction(jsi::Runtime &runtime, double driverId);
|
|
54
55
|
int32_t animateTiming(
|
|
55
56
|
jsi::Runtime &runtime,
|
package/ios/SmoothClipView.mm
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#import "SmoothClipGeometry.h"
|
|
4
4
|
#import "SmoothClipViewRegistry.h"
|
|
5
5
|
|
|
6
|
+
#include "SmoothClipAnimationCurve.h"
|
|
6
7
|
#include "SmoothClipVelocityTracker.h"
|
|
7
8
|
|
|
8
9
|
#import <QuartzCore/QuartzCore.h>
|
|
@@ -89,11 +90,6 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
89
90
|
smoothclip::TimingAnimation _timingAnimation;
|
|
90
91
|
smoothclip::SpringAnimation _springAnimation;
|
|
91
92
|
SmoothClipAnimationDelegate *_animationDelegate;
|
|
92
|
-
BOOL _animationPaused;
|
|
93
|
-
CGRect _pausedRect;
|
|
94
|
-
CGFloat _pausedRadius;
|
|
95
|
-
CGPoint _pausedContentTranslation;
|
|
96
|
-
CFTimeInterval _pausedRemaining;
|
|
97
93
|
|
|
98
94
|
// 'inherit' velocity samples (normalized geometry, per view); recording/
|
|
99
95
|
// coalescing/projection live in the shared cpp/SmoothClipVelocityTracker.h
|
|
@@ -150,24 +146,15 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
150
146
|
_activeAnimationId = 0;
|
|
151
147
|
_activeAnimationKind = 0;
|
|
152
148
|
_pendingAnimationInstall = NO;
|
|
153
|
-
_animationPaused = NO;
|
|
154
149
|
smoothclip::clearVelocitySamples(_velocitySamples);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
name:UIApplicationWillResignActiveNotification
|
|
159
|
-
object:nil];
|
|
160
|
-
[[NSNotificationCenter defaultCenter]
|
|
161
|
-
addObserver:self
|
|
162
|
-
selector:@selector(applicationDidBecomeActive)
|
|
163
|
-
name:UIApplicationDidBecomeActiveNotification
|
|
164
|
-
object:nil];
|
|
150
|
+
// App-state transitions are observed by the registry itself (see
|
|
151
|
+
// installApplicationStateObservers): the active flag is process-global,
|
|
152
|
+
// so its observer must outlive any individual view.
|
|
165
153
|
}
|
|
166
154
|
return self;
|
|
167
155
|
}
|
|
168
156
|
|
|
169
157
|
- (void)dealloc {
|
|
170
|
-
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
171
158
|
if (_driverId != 0) {
|
|
172
159
|
smoothclip::unregisterView(_driverId, self);
|
|
173
160
|
}
|
|
@@ -175,8 +162,8 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
175
162
|
|
|
176
163
|
- (void)didMoveToWindow {
|
|
177
164
|
[super didMoveToWindow];
|
|
178
|
-
if (_driverId != 0
|
|
179
|
-
smoothclip::
|
|
165
|
+
if (_driverId != 0) {
|
|
166
|
+
smoothclip::viewDisplayabilityChanged(_driverId, self);
|
|
180
167
|
}
|
|
181
168
|
}
|
|
182
169
|
|
|
@@ -332,11 +319,17 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
332
319
|
}
|
|
333
320
|
|
|
334
321
|
- (void)smoothClipApplyPresentation:(smoothclip::Presentation)presentation {
|
|
335
|
-
|
|
322
|
+
[self smoothClipApplyPresentation:presentation recordVelocitySample:YES];
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
- (void)smoothClipApplyPresentation:(smoothclip::Presentation)presentation
|
|
326
|
+
recordVelocitySample:(BOOL)recordVelocitySample {
|
|
336
327
|
[self stopLayerAnimationWithoutCallback];
|
|
337
328
|
[self storeRequestedPresentation:presentation];
|
|
338
329
|
[self applyRequestedClip];
|
|
339
|
-
|
|
330
|
+
// Skipped for writes that are not interactive motion (a latched
|
|
331
|
+
// cancel-to-target): they must not enter the 'inherit' history.
|
|
332
|
+
if (recordVelocitySample && _hasLayout) {
|
|
340
333
|
[self recordInteractiveRect:_normalizedClip
|
|
341
334
|
radius:_normalizedRadius
|
|
342
335
|
contentTranslation:_normalizedContentTranslation];
|
|
@@ -366,20 +359,35 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
366
359
|
- (BOOL)smoothClipIsJoinable {
|
|
367
360
|
// A view without layout reports zero geometry from
|
|
368
361
|
// smoothClipCurrentPresentation and must not be used as a join reference.
|
|
369
|
-
return _hasLayout
|
|
362
|
+
return _hasLayout && self.bounds.size.width > 0 &&
|
|
363
|
+
self.bounds.size.height > 0;
|
|
370
364
|
}
|
|
371
365
|
|
|
372
366
|
- (BOOL)smoothClipCanDisplay {
|
|
373
367
|
// A CA animation committed while this view's layer tree is detached from
|
|
374
368
|
// the render tree does not survive the later attach commit; installs and
|
|
375
369
|
// latch starts must wait until a frame can actually be produced.
|
|
376
|
-
return
|
|
370
|
+
return [self smoothClipIsJoinable] && self.window != nil &&
|
|
371
|
+
smoothclip::applicationIsActive();
|
|
377
372
|
}
|
|
378
373
|
|
|
379
374
|
- (BOOL)smoothClipHasPendingInstall {
|
|
380
375
|
return _pendingAnimationInstall;
|
|
381
376
|
}
|
|
382
377
|
|
|
378
|
+
- (void)smoothClipClearVelocitySamples {
|
|
379
|
+
smoothclip::clearVelocitySamples(_velocitySamples);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
- (double)smoothClipSpringContinuationVelocity {
|
|
383
|
+
if (_activeAnimationId == 0 || _activeAnimationKind != 2 ||
|
|
384
|
+
_pendingAnimationInstall) {
|
|
385
|
+
return 0;
|
|
386
|
+
}
|
|
387
|
+
const double elapsed = MAX(0, CACurrentMediaTime() - _animationStartedAt);
|
|
388
|
+
return smoothclip::springContinuationVelocity(_springAnimation, elapsed);
|
|
389
|
+
}
|
|
390
|
+
|
|
383
391
|
- (smoothclip::Presentation)smoothClipFreezePresentation {
|
|
384
392
|
const smoothclip::Presentation visible =
|
|
385
393
|
[self smoothClipCurrentPresentation];
|
|
@@ -391,7 +399,6 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
391
399
|
const CGPoint visibleContentTranslation = CGPointMake(
|
|
392
400
|
visible.contentTranslateX,
|
|
393
401
|
visible.contentTranslateY);
|
|
394
|
-
_animationPaused = NO;
|
|
395
402
|
[self stopLayerAnimationWithoutCallback];
|
|
396
403
|
_requestedClip = visibleRect;
|
|
397
404
|
_requestedRadius = visible.clip.radius;
|
|
@@ -399,9 +406,6 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
399
406
|
[self writeLayerRect:visibleRect radius:visible.clip.radius];
|
|
400
407
|
[self writeContentTranslation:visibleContentTranslation];
|
|
401
408
|
[self syncVisibilityForRect:visibleRect];
|
|
402
|
-
[self recordInteractiveRect:visibleRect
|
|
403
|
-
radius:visible.clip.radius
|
|
404
|
-
contentTranslation:visibleContentTranslation];
|
|
405
409
|
return visible;
|
|
406
410
|
}
|
|
407
411
|
|
|
@@ -432,7 +436,6 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
432
436
|
_ignoreAnimationCallback = NO;
|
|
433
437
|
_activeAnimationId = 0;
|
|
434
438
|
_activeAnimationKind = 0;
|
|
435
|
-
_animationPaused = NO;
|
|
436
439
|
_animationDelegate = nil;
|
|
437
440
|
}
|
|
438
441
|
|
|
@@ -623,13 +626,13 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
623
626
|
forKey:@"smoothClip.content"];
|
|
624
627
|
}
|
|
625
628
|
|
|
626
|
-
- (
|
|
629
|
+
- (BOOL)startAnimationToRequestedGeometryWithDuration:(CFTimeInterval)duration {
|
|
627
630
|
if (![self smoothClipCanDisplay]) {
|
|
628
631
|
_pendingAnimationInstall = YES;
|
|
629
|
-
return;
|
|
632
|
+
return NO;
|
|
630
633
|
}
|
|
631
634
|
SmoothNormalizedClipGeometry target;
|
|
632
|
-
if (![self normalizedRequestedGeometry:&target]) return;
|
|
635
|
+
if (![self normalizedRequestedGeometry:&target]) return NO;
|
|
633
636
|
const smoothclip::Presentation current = [self smoothClipCurrentPresentation];
|
|
634
637
|
[self installAnimationFromRect:CGRectMake(
|
|
635
638
|
current.clip.x,
|
|
@@ -644,20 +647,21 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
644
647
|
toRadius:target.radius
|
|
645
648
|
toContentTranslation:_requestedContentTranslation
|
|
646
649
|
duration:duration];
|
|
650
|
+
return YES;
|
|
647
651
|
}
|
|
648
652
|
|
|
649
|
-
- (
|
|
653
|
+
- (BOOL)smoothClipAnimateTiming:(smoothclip::Presentation)presentation
|
|
650
654
|
animation:(smoothclip::TimingAnimation)animation
|
|
651
655
|
animationId:(int32_t)animationId {
|
|
652
656
|
[self storeRequestedPresentation:presentation];
|
|
653
657
|
_timingAnimation = animation;
|
|
654
658
|
_activeAnimationKind = 1;
|
|
655
659
|
_activeAnimationId = animationId;
|
|
656
|
-
[self startAnimationToRequestedGeometryWithDuration:
|
|
657
|
-
|
|
660
|
+
return [self startAnimationToRequestedGeometryWithDuration:
|
|
661
|
+
MAX(0, animation.durationMs) / 1000.0];
|
|
658
662
|
}
|
|
659
663
|
|
|
660
|
-
- (
|
|
664
|
+
- (BOOL)smoothClipAnimateSpring:(smoothclip::Presentation)presentation
|
|
661
665
|
animation:(smoothclip::SpringAnimation)animation
|
|
662
666
|
animationId:(int32_t)animationId {
|
|
663
667
|
[self storeRequestedPresentation:presentation];
|
|
@@ -675,7 +679,7 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
675
679
|
}
|
|
676
680
|
_activeAnimationKind = 2;
|
|
677
681
|
_activeAnimationId = animationId;
|
|
678
|
-
[self startAnimationToRequestedGeometryWithDuration:0];
|
|
682
|
+
return [self startAnimationToRequestedGeometryWithDuration:0];
|
|
679
683
|
}
|
|
680
684
|
|
|
681
685
|
- (CAKeyframeAnimation *)keyframeAnimationForKeyPath:(NSString *)keyPath
|
|
@@ -689,17 +693,17 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
689
693
|
return animation;
|
|
690
694
|
}
|
|
691
695
|
|
|
692
|
-
- (
|
|
696
|
+
- (BOOL)smoothClipAnimateKeyframes:(smoothclip::Presentation)presentation
|
|
693
697
|
keyframes:(const std::vector<smoothclip::Keyframe> &)keyframes
|
|
694
698
|
durationMs:(double)durationMs
|
|
695
699
|
animationId:(int32_t)animationId {
|
|
696
|
-
if (keyframes.size() < 2) return;
|
|
700
|
+
if (keyframes.size() < 2) return NO;
|
|
697
701
|
[self storeRequestedPresentation:presentation];
|
|
698
702
|
_activeAnimationKind = 3;
|
|
699
703
|
_activeAnimationId = animationId;
|
|
700
704
|
if (![self smoothClipCanDisplay]) {
|
|
701
705
|
_pendingAnimationInstall = YES;
|
|
702
|
-
return;
|
|
706
|
+
return NO;
|
|
703
707
|
}
|
|
704
708
|
[self stopLayerAnimationWithoutCallback];
|
|
705
709
|
_activeAnimationKind = 3;
|
|
@@ -726,7 +730,7 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
726
730
|
frame.presentation.clip.height,
|
|
727
731
|
frame.presentation.clip.radius,
|
|
728
732
|
hostSize,
|
|
729
|
-
&normalized)) return;
|
|
733
|
+
&normalized)) return NO;
|
|
730
734
|
[times addObject:@(frame.offset)];
|
|
731
735
|
[boundsValues addObject:[NSValue valueWithCGRect:normalized.rect]];
|
|
732
736
|
[positionValues addObject:[NSValue valueWithCGPoint:CGPointMake(
|
|
@@ -737,7 +741,7 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
737
741
|
}
|
|
738
742
|
|
|
739
743
|
SmoothNormalizedClipGeometry target;
|
|
740
|
-
if (![self normalizedRequestedGeometry:&target]) return;
|
|
744
|
+
if (![self normalizedRequestedGeometry:&target]) return NO;
|
|
741
745
|
[self writeLayerRect:target.rect radius:target.radius];
|
|
742
746
|
[self writeContentTranslation:_requestedContentTranslation];
|
|
743
747
|
[self setClipContainerHidden:NO];
|
|
@@ -776,6 +780,7 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
776
780
|
[_clipContainer.layer addAnimation:group forKey:@"smoothClip.geometry"];
|
|
777
781
|
[_contentContainer.layer addAnimation:contentGroup
|
|
778
782
|
forKey:@"smoothClip.content"];
|
|
783
|
+
return YES;
|
|
779
784
|
}
|
|
780
785
|
|
|
781
786
|
- (void)smoothClipCancelAnimationUsingTarget:(BOOL)useTarget {
|
|
@@ -790,7 +795,6 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
790
795
|
const CGPoint visibleContentTranslation = CGPointMake(
|
|
791
796
|
visible.contentTranslateX,
|
|
792
797
|
visible.contentTranslateY);
|
|
793
|
-
_animationPaused = NO;
|
|
794
798
|
[self stopLayerAnimationWithoutCallback];
|
|
795
799
|
if (useTarget) {
|
|
796
800
|
[self applyRequestedClip];
|
|
@@ -801,54 +805,6 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
801
805
|
[self writeLayerRect:visibleRect radius:visible.clip.radius];
|
|
802
806
|
[self writeContentTranslation:visibleContentTranslation];
|
|
803
807
|
[self syncVisibilityForRect:visibleRect];
|
|
804
|
-
[self recordInteractiveRect:visibleRect
|
|
805
|
-
radius:visible.clip.radius
|
|
806
|
-
contentTranslation:visibleContentTranslation];
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
- (void)applicationWillResignActive {
|
|
811
|
-
if (_activeAnimationId == 0 || _animationPaused) return;
|
|
812
|
-
const smoothclip::Presentation visible =
|
|
813
|
-
[self smoothClipCurrentPresentation];
|
|
814
|
-
_pausedRect = CGRectMake(
|
|
815
|
-
visible.clip.x,
|
|
816
|
-
visible.clip.y,
|
|
817
|
-
visible.clip.width,
|
|
818
|
-
visible.clip.height);
|
|
819
|
-
_pausedRadius = visible.clip.radius;
|
|
820
|
-
_pausedContentTranslation = CGPointMake(
|
|
821
|
-
visible.contentTranslateX,
|
|
822
|
-
visible.contentTranslateY);
|
|
823
|
-
_pausedRemaining = MAX(
|
|
824
|
-
0, _animationDuration - (CACurrentMediaTime() - _animationStartedAt));
|
|
825
|
-
const int32_t animationId = _activeAnimationId;
|
|
826
|
-
const NSInteger animationKind = _activeAnimationKind;
|
|
827
|
-
[self stopLayerAnimationWithoutCallback];
|
|
828
|
-
_activeAnimationId = animationId;
|
|
829
|
-
_activeAnimationKind = animationKind;
|
|
830
|
-
[self writeLayerRect:_pausedRect radius:_pausedRadius];
|
|
831
|
-
[self writeContentTranslation:_pausedContentTranslation];
|
|
832
|
-
_animationPaused = YES;
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
- (void)applicationDidBecomeActive {
|
|
836
|
-
if (!_animationPaused || _activeAnimationId == 0) return;
|
|
837
|
-
_animationPaused = NO;
|
|
838
|
-
SmoothNormalizedClipGeometry target;
|
|
839
|
-
if ([self normalizedRequestedGeometry:&target]) {
|
|
840
|
-
if (_activeAnimationKind == 3) {
|
|
841
|
-
_activeAnimationKind = 1;
|
|
842
|
-
_timingAnimation = {
|
|
843
|
-
_pausedRemaining * 1000.0, 0, 0, 1, 1, 2};
|
|
844
|
-
}
|
|
845
|
-
[self installAnimationFromRect:_pausedRect
|
|
846
|
-
fromRadius:_pausedRadius
|
|
847
|
-
fromContentTranslation:_pausedContentTranslation
|
|
848
|
-
toRect:target.rect
|
|
849
|
-
toRadius:target.radius
|
|
850
|
-
toContentTranslation:_requestedContentTranslation
|
|
851
|
-
duration:_pausedRemaining];
|
|
852
808
|
}
|
|
853
809
|
}
|
|
854
810
|
|
|
@@ -858,7 +814,6 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
858
814
|
if (_ignoreAnimationCallback || animationId != _activeAnimationId) return;
|
|
859
815
|
_activeAnimationId = 0;
|
|
860
816
|
_activeAnimationKind = 0;
|
|
861
|
-
_animationPaused = NO;
|
|
862
817
|
_animationDelegate = nil;
|
|
863
818
|
[self syncVisibilityForRect:_normalizedClip];
|
|
864
819
|
smoothclip::viewAnimationDidStop(
|
|
@@ -908,31 +863,10 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
908
863
|
|
|
909
864
|
- (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
|
|
910
865
|
oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics {
|
|
911
|
-
if (!_hasLayout && _pendingAnimationInstall && _driverId != 0) {
|
|
912
|
-
// A native animation install arrived before the first layout. Join it now
|
|
913
|
-
// through the registry so it starts from live presentation geometry with
|
|
914
|
-
// the true remaining duration instead of jumping to the target.
|
|
915
|
-
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
916
|
-
_hasLayout = YES;
|
|
917
|
-
[self layoutContentContainer];
|
|
918
|
-
if (self.window == nil) {
|
|
919
|
-
// Still detached (transparentModal subtree before presentation): an
|
|
920
|
-
// install here would not survive the attach commit. Keep the install
|
|
921
|
-
// pending; didMoveToWindow completes it.
|
|
922
|
-
return;
|
|
923
|
-
}
|
|
924
|
-
_pendingAnimationInstall = NO;
|
|
925
|
-
if (!smoothclip::joinActiveAnimation(_driverId, self)) {
|
|
926
|
-
// The animation finished or was cancelled while awaiting layout.
|
|
927
|
-
_activeAnimationId = 0;
|
|
928
|
-
_activeAnimationKind = 0;
|
|
929
|
-
[self applyRequestedClip];
|
|
930
|
-
}
|
|
931
|
-
return;
|
|
932
|
-
}
|
|
933
866
|
CGFloat visibleRadius = 0;
|
|
934
867
|
const BOOL wasAnimating = _activeAnimationId != 0;
|
|
935
|
-
const
|
|
868
|
+
const BOOL wasPending = _pendingAnimationInstall;
|
|
869
|
+
const smoothclip::Presentation visible = wasAnimating && !wasPending
|
|
936
870
|
? [self smoothClipCurrentPresentation]
|
|
937
871
|
: smoothclip::Presentation{{0, 0, 0, 0, 0}, 0, 0};
|
|
938
872
|
const CGRect visibleRect = CGRectMake(
|
|
@@ -944,43 +878,49 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
944
878
|
const CGPoint visibleContentTranslation = CGPointMake(
|
|
945
879
|
visible.contentTranslateX,
|
|
946
880
|
visible.contentTranslateY);
|
|
947
|
-
|
|
881
|
+
CFTimeInterval remaining = wasAnimating
|
|
948
882
|
? MAX(0, _animationDuration -
|
|
949
883
|
(CACurrentMediaTime() - _animationStartedAt))
|
|
950
884
|
: 0;
|
|
885
|
+
const double springContinuationVelocity =
|
|
886
|
+
wasAnimating && !wasPending && _activeAnimationKind == 2
|
|
887
|
+
? [self smoothClipSpringContinuationVelocity]
|
|
888
|
+
: 0;
|
|
951
889
|
|
|
952
890
|
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
953
891
|
_hasLayout = YES;
|
|
954
892
|
[self layoutContentContainer];
|
|
955
|
-
if (
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
if (![self smoothClipCanDisplay])
|
|
971
|
-
// Relayout while detached, with an animation dispatched to this view
|
|
972
|
-
// (a transparentModal subtree resized before presentation): an install
|
|
973
|
-
// from this commit would not survive the attach commit. Keep the
|
|
974
|
-
// install deferred; didMoveToWindow completes it via the registry join.
|
|
975
|
-
_pendingAnimationInstall = YES;
|
|
976
|
-
return;
|
|
977
|
-
}
|
|
893
|
+
if (_driverId != 0) {
|
|
894
|
+
// Both edges matter: zero size/detach/background suspend an installed
|
|
895
|
+
// participant; the first positive visible layout resumes the held latch.
|
|
896
|
+
smoothclip::viewDisplayabilityChanged(_driverId, self);
|
|
897
|
+
}
|
|
898
|
+
if (wasPending) {
|
|
899
|
+
// The registry either kept the install deferred or installed the rebased
|
|
900
|
+
// latch. Relayout must not independently restart a background-held id.
|
|
901
|
+
if (_activeAnimationId == 0) [self applyRequestedClip];
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
if (wasAnimating) {
|
|
905
|
+
// A negative transition may have frozen this host and re-latched the
|
|
906
|
+
// registry above. Its non-recording freeze is already the correct model
|
|
907
|
+
// state for the new lifecycle; do not resurrect a local timer.
|
|
908
|
+
if (_activeAnimationId == 0 || ![self smoothClipCanDisplay]) return;
|
|
978
909
|
const int32_t animationId = _activeAnimationId;
|
|
979
910
|
const NSInteger animationKind = _activeAnimationKind;
|
|
980
911
|
[self stopLayerAnimationWithoutCallback];
|
|
981
912
|
_activeAnimationId = animationId;
|
|
982
913
|
_activeAnimationKind = animationKind;
|
|
983
|
-
if (_activeAnimationKind ==
|
|
914
|
+
if (_activeAnimationKind == 1 && _animationDuration > 0) {
|
|
915
|
+
const double progress = smoothclip::clamp01(
|
|
916
|
+
1 - remaining / _animationDuration);
|
|
917
|
+
_timingAnimation =
|
|
918
|
+
smoothclip::timingRemainder(_timingAnimation, progress).animation;
|
|
919
|
+
remaining = _timingAnimation.durationMs / 1000.0;
|
|
920
|
+
} else if (_activeAnimationKind == 2) {
|
|
921
|
+
_springAnimation.initialVelocity = springContinuationVelocity;
|
|
922
|
+
_springAnimation.inheritVelocity = false;
|
|
923
|
+
} else if (_activeAnimationKind == 3) {
|
|
984
924
|
_activeAnimationKind = 1;
|
|
985
925
|
_timingAnimation = {remaining * 1000.0, 0, 0, 1, 1, 2};
|
|
986
926
|
}
|
|
@@ -1004,6 +944,12 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
1004
944
|
duration:remaining];
|
|
1005
945
|
}
|
|
1006
946
|
} else {
|
|
947
|
+
if (_driverId != 0 && smoothclip::hasActiveAnimation(_driverId)) {
|
|
948
|
+
// Registry-level lifecycle pause owns the frozen model. A layout pass
|
|
949
|
+
// while its latch is held must not apply the requested target or start a
|
|
950
|
+
// per-view timer; foreground/reattach will normalize and resume it once.
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
1007
953
|
[self applyRequestedClip];
|
|
1008
954
|
}
|
|
1009
955
|
}
|
|
@@ -1071,7 +1017,6 @@ static std::array<double, 7> SmoothClipVelocityChannels(
|
|
|
1071
1017
|
}
|
|
1072
1018
|
[self stopLayerAnimationWithoutCallback];
|
|
1073
1019
|
_pendingAnimationInstall = NO;
|
|
1074
|
-
_animationPaused = NO;
|
|
1075
1020
|
smoothclip::clearVelocitySamples(_velocitySamples);
|
|
1076
1021
|
[super prepareForRecycle];
|
|
1077
1022
|
_requestedClip = CGRectZero;
|
|
@@ -23,7 +23,10 @@ bool joinActiveAnimation(uint64_t driverId, SmoothClipView *view);
|
|
|
23
23
|
// A CA animation committed while the host's layer tree is detached (e.g. a
|
|
24
24
|
// transparentModal subtree before its view controller is presented) does not
|
|
25
25
|
// survive the attach commit; installs must therefore wait for this signal.
|
|
26
|
-
void
|
|
26
|
+
void viewDisplayabilityChanged(uint64_t driverId, SmoothClipView *view);
|
|
27
|
+
void applicationWillResignActive();
|
|
28
|
+
void applicationDidBecomeActive();
|
|
29
|
+
bool applicationIsActive();
|
|
27
30
|
void viewAnimationDidStop(
|
|
28
31
|
uint64_t driverId,
|
|
29
32
|
int32_t animationId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeSmoothClipModule.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeSmoothClipModule.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AAuGlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,wBAAwB,CAAC","ignoreList":[]}
|
|
@@ -24,6 +24,14 @@ export function detachDriverState(state) {
|
|
|
24
24
|
if (statesById.get(state.driverId) === state) {
|
|
25
25
|
statesById.delete(state.driverId);
|
|
26
26
|
}
|
|
27
|
+
// Requests pending at teardown were settled by rejectDriverRequests, but
|
|
28
|
+
// their completion deferrals can no longer be released: the late-scheduled
|
|
29
|
+
// resolver's releaseDriverCompletions no-ops against a detached state. An
|
|
30
|
+
// effect replay reattaches THIS same object, so a stale positive count
|
|
31
|
+
// would queue every future completion forever. The deferrals died with
|
|
32
|
+
// their requests — reset them.
|
|
33
|
+
state.completionDeferrals = 0;
|
|
34
|
+
state.deferredCompletions.length = 0;
|
|
27
35
|
}
|
|
28
36
|
export function createDriverState(driverId, initialPresentation, source, onAnimationComplete, activeAnimationId, ownership) {
|
|
29
37
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["states","WeakMap","statesById","Map","nextDriverId","Date","now","allocateDriverId","Number","isSafeInteger","setDriverState","driver","state","set","attachDriverState","driverId","detachDriverState","get","delete","createDriverState","initialPresentation","source","onAnimationComplete","activeAnimationId","ownership","mountedViews","Set","animationParticipants","failedAnimations","
|
|
1
|
+
{"version":3,"names":["states","WeakMap","statesById","Map","nextDriverId","Date","now","allocateDriverId","Number","isSafeInteger","setDriverState","driver","state","set","attachDriverState","driverId","detachDriverState","get","delete","completionDeferrals","deferredCompletions","length","createDriverState","initialPresentation","source","onAnimationComplete","activeAnimationId","ownership","mountedViews","Set","animationParticipants","failedAnimations","registerDriverView","getDriverState","token","add","animationId","participants","has","snapshotDriverViews","finishDriverAnimation","finished","result","deliverDriverCompletion","push","current","deferDriverCompletions","releaseDriverCompletions","deferred","splice","Error"],"sourceRoot":"../../src","sources":["driverState.ts"],"mappings":"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","ignoreList":[]}
|