From 490ce6bb304e054b0e189c740ed9d5583750a0c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20B=C5=82oniarz?= Date: Tue, 11 Jun 2024 12:21:51 +0200 Subject: [PATCH] Avoid starting animations for non-layout updates --- .../cpp/LayoutAnimations/LayoutAnimationsProxy.cpp | 14 ++++++++++++-- .../cpp/LayoutAnimations/LayoutAnimationsProxy.h | 3 +++ .../cpp/LayoutAnimations/LayoutAnimationsUtils.h | 4 ++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp b/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp index d1e87b52fed..85e4262cd1d 100644 --- a/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp +++ b/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp @@ -314,7 +314,8 @@ void LayoutAnimationsProxy::handleUpdatesAndEnterings( } case ShadowViewMutation::Type::Update: { - if (!layoutAnimationsManager_->hasLayoutAnimation(tag, LAYOUT)) { + auto shouldAnimate = hasLayoutChanged(mutation); + if (!layoutAnimationsManager_->hasLayoutAnimation(tag, LAYOUT) || (!shouldAnimate && !layoutAnimations_.contains(tag))) { // We should cancel any ongoing animation here to ensure that the // proper final state is reached for this view However, due to how // RNSScreens handle adding headers (a second commit is triggered to @@ -324,6 +325,9 @@ void LayoutAnimationsProxy::handleUpdatesAndEnterings( // TODO: find a better solution for this problem filteredMutations.push_back(mutation); continue; + } else if (!shouldAnimate){ + updateOngoingAnimationTarget(tag, mutation); + continue; } startLayoutAnimation(tag, mutation); break; @@ -644,7 +648,7 @@ void LayoutAnimationsProxy::startLayoutAnimation( auto parentView = std::make_shared(mutation.parentShadowView); layoutAnimations_.insert_or_assign( tag, LayoutAnimation{finalView, currentView, parentView, {}, count}); - + Snapshot currentValues(oldView, surfaceManager.getWindow(surfaceId)); Snapshot targetValues( mutation.newChildShadowView, surfaceManager.getWindow(surfaceId)); @@ -671,6 +675,12 @@ void LayoutAnimationsProxy::startLayoutAnimation( }); } +void LayoutAnimationsProxy::updateOngoingAnimationTarget( + const int tag, + const ShadowViewMutation &mutation) const { + layoutAnimations_[tag].finalView = std::make_shared(mutation.newChildShadowView); +} + void LayoutAnimationsProxy::maybeCancelAnimation(const int tag) const { if (!layoutAnimations_.contains(tag)) { return; diff --git a/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.h b/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.h index 9a65ea3cbbf..7ada07c2d73 100644 --- a/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.h +++ b/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.h @@ -82,6 +82,9 @@ struct LayoutAnimationsProxy : public MountingOverrideDelegate { void addOngoingAnimations( SurfaceId surfaceId, ShadowViewMutationList &mutations) const; + void updateOngoingAnimationTarget( + const int tag, + const ShadowViewMutation& mutation) const; void updateIndexForMutation(ShadowViewMutation &mutation) const; diff --git a/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsUtils.h b/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsUtils.h index b632af1dece..03a11477340 100644 --- a/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsUtils.h +++ b/packages/react-native-reanimated/Common/cpp/LayoutAnimations/LayoutAnimationsUtils.h @@ -145,6 +145,10 @@ static inline bool isRNSScreen(std::shared_ptr node) { node->mutation.oldChildShadowView.componentName, "RNSScreen"); } +static inline bool hasLayoutChanged(const ShadowViewMutation& mutation){ + return mutation.oldChildShadowView.layoutMetrics.frame != mutation.newChildShadowView.layoutMetrics.frame; +} + static inline void mergeAndSwap(std::vector>& A, std::vector>& B){ std::vector> merged; auto it1 = A.begin(), it2 = B.begin();