Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9395a59
Update layout animations
bartlomiejbloniarz Nov 13, 2023
272399c
Add example
bartlomiejbloniarz Nov 13, 2023
fd7aaea
batchinator
bartlomiejbloniarz Nov 17, 2023
de8c246
`'use strict'` 😭
bartlomiejbloniarz Nov 17, 2023
2ee764d
Mock web
bartlomiejbloniarz Nov 17, 2023
ee5eae0
Fix `enableLayoutAnimations` call
bartlomiejbloniarz Nov 20, 2023
9d480e9
Fix overlapping layout animations
bartlomiejbloniarz Nov 20, 2023
73603db
Fix `MethodMetadata`
bartlomiejbloniarz Nov 20, 2023
722ec07
Update docs
bartlomiejbloniarz Nov 21, 2023
056deb8
Merge branch 'main' into @bartlomiejbloniarz/modify-layout-animations
bartlomiejbloniarz Nov 21, 2023
9c77015
Merge branch 'main' into @bartlomiejbloniarz/modify-layout-animations
bartlomiejbloniarz Nov 22, 2023
cc02106
Merge branch 'main' into @bartlomiejbloniarz/modify-layout-animations
bartlomiejbloniarz Nov 22, 2023
efbd197
Big commit
bartlomiejbloniarz Dec 13, 2023
778fa63
change Android implementation
bartlomiejbloniarz Dec 29, 2023
a30284a
Remove unnecessary configuration calls
bartlomiejbloniarz Jan 8, 2024
aaf7149
Move animation start to `willAppear`
bartlomiejbloniarz Jan 8, 2024
f3debe0
Fix interactivity
bartlomiejbloniarz Jan 12, 2024
05bac12
merg
bartlomiejbloniarz Jan 15, 2024
577feea
fix java lint
bartlomiejbloniarz Jan 15, 2024
15974e1
Merge branch 'main' into @bartlomiejbloniarz/modify-sets
bartlomiejbloniarz Jan 17, 2024
1771706
Add tsdoc
bartlomiejbloniarz Jan 17, 2024
6adce90
Fix transforms on iOS
bartlomiejbloniarz Jan 24, 2024
6de03aa
Simplify configuration
bartlomiejbloniarz Jan 24, 2024
a9a5461
Remove old api
bartlomiejbloniarz Jan 26, 2024
7b3d4dc
Add comment
bartlomiejbloniarz Jan 26, 2024
0b0fcdc
Fix [SET] Modals example
bartlomiejbloniarz Jan 26, 2024
5748249
Change config cleanup
bartlomiejbloniarz Jan 26, 2024
c5ae961
Rename listener
bartlomiejbloniarz Jan 26, 2024
2ccf49e
merg
bartlomiejbloniarz Jan 26, 2024
bfd5391
Split cleanup for shared transitions
bartlomiejbloniarz Feb 21, 2024
3d04f0f
Merge main
piaskowyk Mar 8, 2024
17add2d
Update name
piaskowyk Mar 8, 2024
b2eaf60
Merge branch 'main' into @bartlomiejbloniarz/modify-sets
piaskowyk Mar 15, 2024
260614f
Improvements after review
piaskowyk Mar 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 40 additions & 32 deletions Common/cpp/LayoutAnimations/LayoutAnimationsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,50 @@

namespace reanimated {

void LayoutAnimationsManager::configureAnimation(
const int tag,
const LayoutAnimationType type,
const std::string &sharedTransitionTag,
const std::shared_ptr<Shareable> &config) {
auto lock = std::unique_lock<std::mutex>(animationsMutex_);
if (type == SHARED_ELEMENT_TRANSITION ||
type == SHARED_ELEMENT_TRANSITION_PROGRESS) {
void LayoutAnimationsManager::configureAnimationBatch(
const std::vector<LayoutAnimationConfig> &layoutAnimationsBatch) {
auto lock = std::unique_lock<std::recursive_mutex>(animationsMutex_);
std::vector<LayoutAnimationConfig> sharedTransitionConfigs;
for (auto layoutAnimationConfig : layoutAnimationsBatch) {
const auto &[tag, type, config, sharedTransitionTag] =
layoutAnimationConfig;
if (type == SHARED_ELEMENT_TRANSITION ||
type == SHARED_ELEMENT_TRANSITION_PROGRESS) {
clearSharedTransitionConfig(tag);
sharedTransitionConfigs.push_back(std::move(layoutAnimationConfig));
} else {
if (config == nullptr) {
getConfigsForType(type).erase(tag);
} else {
getConfigsForType(type)[tag] = config;
}
}
}
for (const auto &[tag, type, config, sharedTransitionTag] :
sharedTransitionConfigs) {
if (config == nullptr) {
continue;
}
sharedTransitionGroups_[sharedTransitionTag].push_back(tag);
viewTagToSharedTag_[tag] = sharedTransitionTag;
getConfigsForType(SHARED_ELEMENT_TRANSITION)[tag] = config;
if (type == SHARED_ELEMENT_TRANSITION) {
ignoreProgressAnimationForTag_.insert(tag);
}
} else {
getConfigsForType(type)[tag] = config;
}
}

void LayoutAnimationsManager::configureAnimationBatch(
const std::vector<LayoutAnimationConfig> &layoutAnimationsBatch) {
auto lock = std::unique_lock<std::mutex>(animationsMutex_);
for (auto [tag, type, config] : layoutAnimationsBatch) {
if (config == nullptr) {
getConfigsForType(type).erase(tag);
} else {
getConfigsForType(type)[tag] = config;
}
}
}

void LayoutAnimationsManager::setShouldAnimateExiting(
const int tag,
const bool value) {
auto lock = std::unique_lock<std::mutex>(animationsMutex_);
auto lock = std::unique_lock<std::recursive_mutex>(animationsMutex_);
shouldAnimateExitingForTag_[tag] = value;
}

bool LayoutAnimationsManager::shouldAnimateExiting(
const int tag,
const bool shouldAnimate) {
auto lock = std::unique_lock<std::mutex>(animationsMutex_);
auto lock = std::unique_lock<std::recursive_mutex>(animationsMutex_);
return collection::contains(shouldAnimateExitingForTag_, tag)
? shouldAnimateExitingForTag_[tag]
: shouldAnimate;
Expand All @@ -58,20 +60,16 @@ bool LayoutAnimationsManager::shouldAnimateExiting(
bool LayoutAnimationsManager::hasLayoutAnimation(
const int tag,
const LayoutAnimationType type) {
auto lock = std::unique_lock<std::mutex>(animationsMutex_);
auto lock = std::unique_lock<std::recursive_mutex>(animationsMutex_);
if (type == SHARED_ELEMENT_TRANSITION_PROGRESS) {
auto end = ignoreProgressAnimationForTag_.end();
return ignoreProgressAnimationForTag_.find(tag) == end;
}
return collection::contains(getConfigsForType(type), tag);
}

void LayoutAnimationsManager::clearLayoutAnimationConfig(const int tag) {
auto lock = std::unique_lock<std::mutex>(animationsMutex_);
enteringAnimations_.erase(tag);
exitingAnimations_.erase(tag);
layoutAnimations_.erase(tag);
shouldAnimateExitingForTag_.erase(tag);
void LayoutAnimationsManager::clearSharedTransitionConfig(const int tag) {
auto lock = std::unique_lock<std::recursive_mutex>(animationsMutex_);
#ifndef NDEBUG
const auto &pair = viewsScreenSharedTagMap_[tag];
screenSharedTagSet_.erase(pair);
Expand All @@ -81,6 +79,7 @@ void LayoutAnimationsManager::clearLayoutAnimationConfig(const int tag) {
sharedTransitionAnimations_.erase(tag);
auto const &groupName = viewTagToSharedTag_[tag];
if (groupName.empty()) {
viewTagToSharedTag_.erase(tag);
return;
}
auto &group = sharedTransitionGroups_[groupName];
Expand All @@ -95,14 +94,23 @@ void LayoutAnimationsManager::clearLayoutAnimationConfig(const int tag) {
ignoreProgressAnimationForTag_.erase(tag);
}

void LayoutAnimationsManager::clearLayoutAnimationConfig(const int tag) {
auto lock = std::unique_lock<std::recursive_mutex>(animationsMutex_);
enteringAnimations_.erase(tag);
exitingAnimations_.erase(tag);
layoutAnimations_.erase(tag);
shouldAnimateExitingForTag_.erase(tag);
clearSharedTransitionConfig(tag);
}

void LayoutAnimationsManager::startLayoutAnimation(
jsi::Runtime &rt,
const int tag,
const LayoutAnimationType type,
const jsi::Object &values) {
std::shared_ptr<Shareable> config, viewShareable;
{
auto lock = std::unique_lock<std::mutex>(animationsMutex_);
auto lock = std::unique_lock<std::recursive_mutex>(animationsMutex_);
config = getConfigsForType(type)[tag];
}
// TODO: cache the following!!
Expand Down
9 changes: 3 additions & 6 deletions Common/cpp/LayoutAnimations/LayoutAnimationsManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,13 @@ struct LayoutAnimationConfig {
int tag;
LayoutAnimationType type;
std::shared_ptr<Shareable> config;
std::string sharedTransitionTag;
};

class LayoutAnimationsManager {
public:
explicit LayoutAnimationsManager(const std::shared_ptr<JSLogger> &jsLogger)
: jsLogger_(jsLogger) {}
void configureAnimation(
const int tag,
const LayoutAnimationType type,
const std::string &sharedTransitionTag,
const std::shared_ptr<Shareable> &config);
void configureAnimationBatch(
const std::vector<LayoutAnimationConfig> &layoutAnimationsBatch);
void setShouldAnimateExiting(const int tag, const bool value);
Expand All @@ -44,6 +40,7 @@ class LayoutAnimationsManager {
const LayoutAnimationType type,
const jsi::Object &values);
void clearLayoutAnimationConfig(const int tag);
void clearSharedTransitionConfig(const int tag);
void cancelLayoutAnimation(jsi::Runtime &rt, const int tag) const;
int findPrecedingViewTagForTransition(const int tag);
#ifndef NDEBUG
Expand Down Expand Up @@ -75,7 +72,7 @@ class LayoutAnimationsManager {
std::unordered_map<std::string, std::vector<int>> sharedTransitionGroups_;
std::unordered_map<int, std::string> viewTagToSharedTag_;
std::unordered_map<int, bool> shouldAnimateExitingForTag_;
mutable std::mutex
mutable std::recursive_mutex
animationsMutex_; // Protects `enteringAnimations_`, `exitingAnimations_`,
// `layoutAnimations_`, `viewSharedValues_` and `shouldAnimateExitingForTag_`.
};
Expand Down
27 changes: 10 additions & 17 deletions Common/cpp/NativeModules/NativeReanimatedModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,23 +377,6 @@ jsi::Value NativeReanimatedModule::configureProps(
return jsi::Value::undefined();
}

jsi::Value NativeReanimatedModule::configureLayoutAnimation(
jsi::Runtime &rt,
const jsi::Value &viewTag,
const jsi::Value &type,
const jsi::Value &sharedTransitionTag,
const jsi::Value &config) {
layoutAnimationsManager_.configureAnimation(
viewTag.asNumber(),
static_cast<LayoutAnimationType>(type.asNumber()),
sharedTransitionTag.asString(rt).utf8(rt),
extractShareableOrThrow<ShareableObject>(
rt,
config,
"[Reanimated] Layout animation config must be an object."));
return jsi::Value::undefined();
}

jsi::Value NativeReanimatedModule::configureLayoutAnimationBatch(
jsi::Runtime &rt,
const jsi::Value &layoutAnimationsBatch) {
Expand All @@ -415,6 +398,16 @@ jsi::Value NativeReanimatedModule::configureLayoutAnimationBatch(
config,
"[Reanimated] Layout animation config must be an object.");
}
if (batch[i].type != SHARED_ELEMENT_TRANSITION &&
batch[i].type != SHARED_ELEMENT_TRANSITION_PROGRESS) {
continue;
}
auto sharedTransitionTag = item.getProperty(rt, "sharedTransitionTag");
if (sharedTransitionTag.isUndefined()) {
batch[i].config = nullptr;
} else {
batch[i].sharedTransitionTag = sharedTransitionTag.asString(rt).utf8(rt);
}
}
layoutAnimationsManager_.configureAnimationBatch(batch);
return jsi::Value::undefined();
Expand Down
6 changes: 0 additions & 6 deletions Common/cpp/NativeModules/NativeReanimatedModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec {
jsi::Runtime &rt,
const jsi::Value &uiProps,
const jsi::Value &nativeProps) override;
jsi::Value configureLayoutAnimation(
jsi::Runtime &rt,
const jsi::Value &viewTag,
const jsi::Value &type,
const jsi::Value &sharedTransitionTag,
const jsi::Value &config) override;
jsi::Value configureLayoutAnimationBatch(
jsi::Runtime &rt,
const jsi::Value &layoutAnimationsBatch) override;
Expand Down
16 changes: 0 additions & 16 deletions Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,20 +150,6 @@ static jsi::Value SPEC_PREFIX(unsubscribeFromKeyboardEvents)(
return jsi::Value::undefined();
}

static jsi::Value SPEC_PREFIX(configureLayoutAnimation)(
jsi::Runtime &rt,
TurboModule &turboModule,
const jsi::Value *args,
size_t) {
return static_cast<NativeReanimatedModuleSpec *>(&turboModule)
->configureLayoutAnimation(
rt,
std::move(args[0]),
std::move(args[1]),
std::move(args[2]),
std::move(args[3]));
}

static jsi::Value SPEC_PREFIX(configureLayoutAnimationBatch)(
jsi::Runtime &rt,
TurboModule &turboModule,
Expand Down Expand Up @@ -214,8 +200,6 @@ NativeReanimatedModuleSpec::NativeReanimatedModuleSpec(
methodMap_["unsubscribeFromKeyboardEvents"] =
MethodMetadata{1, SPEC_PREFIX(unsubscribeFromKeyboardEvents)};

methodMap_["configureLayoutAnimation"] =
MethodMetadata{4, SPEC_PREFIX(configureLayoutAnimation)};
methodMap_["configureLayoutAnimationBatch"] =
MethodMetadata{1, SPEC_PREFIX(configureLayoutAnimationBatch)};
methodMap_["setShouldAnimateExitingForTag"] =
Expand Down
7 changes: 0 additions & 7 deletions Common/cpp/NativeModules/NativeReanimatedModuleSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,6 @@ class JSI_EXPORT NativeReanimatedModuleSpec : public TurboModule {
const jsi::Value &nativeProps) = 0;

// layout animations
virtual jsi::Value configureLayoutAnimation(
jsi::Runtime &rt,
const jsi::Value &viewTag,
const jsi::Value &type,
const jsi::Value &sharedTransitionTag,
const jsi::Value &config) = 0;

virtual jsi::Value configureLayoutAnimationBatch(
jsi::Runtime &rt,
const jsi::Value &layoutAnimationsBatch) = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,8 +714,8 @@ private static Point convertScreenLocationToViewCoordinates(Point fromPoint, Vie
return new Point(fromPoint.x - toPoint[0], fromPoint.y - toPoint[1]);
}

public void screenDidLayout() {
mSharedTransitionManager.screenDidLayout();
public void screenDidLayout(View view) {
mSharedTransitionManager.screenDidLayout(view);
}

public void viewDidLayout(View view) {
Expand All @@ -726,6 +726,10 @@ public void notifyAboutViewsRemoval(int[] tagsToDelete) {
mSharedTransitionManager.onViewsRemoval(tagsToDelete);
}

public void notifyAboutScreenWillDisappear() {
mSharedTransitionManager.onScreenWillDisappear();
}

public void makeSnapshotOfTopScreenViews(ViewGroup stack) {
mSharedTransitionManager.doSnapshotForTopScreenViews(stack);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.uimanager.IllegalViewOperationException;
import com.facebook.react.uimanager.NativeViewHierarchyManager;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.ViewAtIndex;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.ViewManagerRegistry;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.layoutanimation.LayoutAnimationController;
import com.facebook.react.uimanager.layoutanimation.LayoutAnimationListener;
import com.swmansion.reanimated.ReanimatedModule;
Expand Down Expand Up @@ -164,6 +167,20 @@ public void deleteView(final View view, final LayoutAnimationListener listener)
if (parentName.equals("RNSScreenStack")) {
mAnimationsManager.cancelAnimationsInSubviews(view);
super.deleteView(view, listener);
EventDispatcher eventDispatcher =
UIManagerHelper.getEventDispatcherForReactTag(
(ReactContext) view.getContext(), view.getId());
if (eventDispatcher != null) {
eventDispatcher.addListener(
event -> {
// we schedule the start of transition for the ScreenWilDisappear event, so that the
// layout of the target screen is already calculated
// this allows us to make snapshots on the go, so that they are always up-to-date
if (event.getEventName().equals("topWillDisappear")) {
getAnimationsManager().notifyAboutScreenWillDisappear();
}
});
}
return;
}
}
Expand Down Expand Up @@ -264,7 +281,7 @@ public synchronized void updateLayout(
if (container != null && viewManagerName.equals("RNSScreen") && mReaLayoutAnimator != null) {
boolean hasHeader = checkIfTopScreenHasHeader((ViewGroup) container);
if (!hasHeader || !container.isLayoutRequested()) {
mReaLayoutAnimator.getAnimationsManager().screenDidLayout();
mReaLayoutAnimator.getAnimationsManager().screenDidLayout(container);
}
}
View view = resolveView(tag);
Expand Down
Loading