Skip to content

Conversation

@bartlomiejbloniarz
Copy link
Contributor

@bartlomiejbloniarz bartlomiejbloniarz commented May 5, 2025

Summary

This PR brings back the Shared Element Transition feature to reanimated (within a limited scope and behind a feature flag).

Current limitations:

  • animations with native modals don't work on iOS (the modal is displayed over the Shared Element). This can be fixed by plugging the Shared Element into the Window, instead of the React's RootVIew.
  • can't define custom progress (swipe back) transitions (it just isn't implemented yet, it was easier to hard code)
  • progress transitions animate less props than basic ones (for the same reason as above)
  • on iOS there are still some issues with header height (e.g. the [SET] Modals) example
  • there are some performance bottlenecks, that stem from transforms being recalculated too eagerly (this requires some changes to how we recognize whether to start a transition)
  • we have to use a workaround for rnscreens to not keep a snapshot of the transitioning view on the popped screen. Currently the fix is available in their nightly release.
  • zIndex of exiting animations changes (they are brought to the front). This differs from the current behaviour.
  • sometimes on a fast refresh, the transition will run for elements that are on the same screen. From our testing it happened when the navigator was wrapped with a context provider, but we didn't investigate it further. The problem was, that in this case the native view that represents the screen actually changed, so the SET logic worked as it should. But it definitely is not the expected outcome
  • with transparentModal on iOS the transitioning view is obstructed by the outgoing screen. This will be fixed once we move from plugging it into RootView, to plugging it into the Window
  • The TabNavigator is not supported yet, using it in the path that uses shared transitions may result in no animation being ran.

Test plan

@slorber
Copy link
Contributor

slorber commented May 7, 2025

Hey 👋

Just backlinking to the PR announcement tweet for demos and community comments: https://x.com/BBloniarz_/status/1919390653856829566

@elozino-eryk
Copy link

Hi @bartlomiejbloniarz nice work you are doing.

Is there a way we can get a code demo of it in new Arch? Currently, I am unable to get it to work with the code sample provide in the docs.

Thanks ❤️

@bglgwyng
Copy link

@elozino-eryk you can see the set of examples by run yarn start in apps/fabric-example

@bartlomiejbloniarz bartlomiejbloniarz added this pull request to the merge queue Dec 3, 2025
Merged via the queue into main with commit 2c3d7fd Dec 3, 2025
24 checks passed
@bartlomiejbloniarz bartlomiejbloniarz deleted the @bartlomiejbloniarz/sets branch December 3, 2025 15:54
@laurens-lamberts
Copy link

laurens-lamberts commented Dec 8, 2025

@bartlomiejbloniarz, I've been following this PR, and I'm happy to see that it is now merged!
The lack of shared element transitions is what was holding us back from updating our app to latest Expo, and using the new architecture. Very excited about this.

Can you help me learn how I can test the new shared element transitions?
I've added this to my package.json and built again, but no sign of the transition yet;

  "reanimated": {
    "staticFeatureFlags": {
      "ENABLE_SHARED_ELEMENT_TRANSITIONS": true
    }
  }

@bartlomiejbloniarz
Copy link
Contributor Author

@laurens-lamberts on iOS you need to also run pod install (here's the instruction)

@laurens-lamberts
Copy link

@laurens-lamberts on iOS you need to also run pod install (here's the instruction)

Thanks for your prompt reply! I've deleted the ios folder before prebuilding with Expo again, so that must have installed pods again, right? No luck yet, but I can try again later this week.

@bartlomiejbloniarz
Copy link
Contributor Author

@laurens-lamberts Maybe expo is doing some aggressive caching there, and it's missing the new flag value?

@laurens-lamberts
Copy link

Hi @bartlomiejbloniarz,

I just tried removing both .expo and ios folders and installing again, but no sign of the transition yet.
I still have everything configured for shared element transitions as I had before with the old architecture (as it currently works in our live app-version). The version of Reanimated I am now testing on is 4.2.0.

Is there some logging I could enable to see what shared element transitions are detected / initiated?

@weemundo
Copy link

weemundo commented Dec 9, 2025

Hi @bartlomiejbloniarz - I am facing the exact same issue that @laurens-lamberts has highlighted. Tried expo prebuild --clean, pod install and cross checked the package.json - everything seems to be as per the doc.

Looking forward to a potential solution, can't wait to try this out!

@wassgha
Copy link

wassgha commented Dec 12, 2025

Experiencing the same issue here, no luck getting shared transitions to work with expo. @weemundo / @laurens-lamberts did you figure out a solution?

@laurens-lamberts
Copy link

@wassgha I haven't looked into this in further detail yet. I hope to be able to troubleshoot this from January.
I'll follow this thread in case someone else manages to find a solution earlier.

@bartlomiejbloniarz
Copy link
Contributor Author

So I tried run it in a new expo app, and it looks fine on my side. the only thing I had to do after adding the feature flag was to run pod install manually. To best debug it you could add logging here to see what layout animations (which includes SETs) are being started. It would also be good to add a breakpoint here to see whether the flag was enabled properly. Also it would be usefull to add a breakpoint here, to see what animations are supposed to start on the native side.

@laurens-lamberts
Copy link

Thanks for the pointers @bartlomiejbloniarz! I hope to test and report back soon.

@laurens-lamberts
Copy link

laurens-lamberts commented Dec 17, 2025

Hi @bartlomiejbloniarz,

I ran the tests as you pointed out, using Reanimated 4.2.0, React Native 0.81.5, Expo 54.0.27, new arch enabled.
I tested react-native-screens versions 4.16.0 (with patch as in this PR) and 4.19.0 (which includes the fix you mentioned in the PR summary). react-navigation packages used are all latest available.

I have this property configured on my Animated.Image (which works using the old arch);
sharedTransitionTag={sharedTransitionTag}

I've just tried logging the layout animations registered via createLayoutAnimationManager, but this is all it is currently logging for me;

{"animations":{"opacity":{"type":"timing","progress":0,"toValue":1,"startValue":0,"startTime":0,"current":1,"reduceMotion":false}},"initialValues":{"opacity":0}}

I believe this is the fade-transition from my main screen to the transparentModal-presentation screen.

I read something about an issue with the new SET when using in combination with a modal, but even when I remove the transparentModal presentation from the screen (resulting in a slide-to-left animation), the SET isn't showing.

Then I tried setting the breakpoints on LayoutAnimationsProxy_Experimental.cpp. I do see both handleSharedTransitionsStart and findSharedElementsOnScreen functions being triggered there.

The breakpoint on void LayoutAnimationsProxy_Experimental::startSharedTransition( however, never gets reached. Not when starting the app, not when navigating to the screen that contains an image with the same sharedTransitionTag.

Not sure if it is related, but the only Xcode logs I can find that might be related is the following;

Unbalanced calls start/end for tag 20
Unbalanced calls start/end for tag 19

Do you have any suggestions on where to look next?
Soon I'll try creating a fresh Expo project and test it there first. After I may try to take away complexity/libraries from my project to see if that gets it going.

@laurens-lamberts
Copy link

laurens-lamberts commented Dec 18, 2025

Update; I just notice it starts to work when I remove my screen from the (react navigation) tab navigator that surrounded it. Do you have an idea why this could be the case? For our use case it would be great to keep the tab navigator in place.

Also, I'm transitioning towards a transparentModal screen, and I find that during the entire SET the origin image is now being masked by a backdrop I've defined in the target screen, until it snaps in front of it on the last transition frame. With the old arch SET, this was not the case (the image transition happened on top of everything). Do you think we can make the transition happen on top again?

@bartlomiejbloniarz
Copy link
Contributor Author

bartlomiejbloniarz commented Dec 18, 2025

Hi I will add these issues to the list of current limitations. The transparentModal is a known issue that will be fixed once we move the animated element from RootView to Window. The TabNavigator isn't supported for animations, but in my testing I didn't see the behavior you are describing. This will require a fix on our side.

Thanks for looking into this, it's very helpful to see what issues people run into in real applications.

@laurens-lamberts
Copy link

I'm happy to help!

We've applied two slight changes to our design to work around the pending issues;

  1. replacing the TabNavigator with a pagingEnabled horizontal ScrollView
  2. having the transparent modal backdrop fade-in just after the SET completed

If any of the issues is fixed, we will revert those to how they were.

We'll be doing some more testing soon, and are planning to release an update of our app with the new transitions in January/February.

Thanks for all your work on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.