Skip to content

Conversation

@thomasttvo
Copy link
Collaborator

@thomasttvo thomasttvo commented Dec 24, 2025

Reanimated implementation is here and now with almost all features preserved. Some features like pin onPress/onLongPress need to be stripped due to time constraint.


Note

Migrates the zoomable view to a Reanimated + Gesture Handler implementation with worklet-driven callbacks and smoother animations; updates the example app and tooling to support the new stack.

  • Core: Replaces legacy Animated/pan logic with Reanimated shared values, worklets, and Manual gesture handling; adds onTransformWorklet and onStaticPinPositionMoveWorklet, preserves double-tap/pinch/shift behavior, and refines static pin updates
  • Example: Refactors to Reanimated (marker scaling via animated style), adds long-press alert and optional Modal wrapper, removes old zoomAnimatedValue
  • Tooling: Adds Reanimated Babel plugin; updates Metro config to alias src and avoid peer duplicates; bumps example to Expo 54/React 19/RN 0.81 and adds react-native-reanimated/gesture-handler/worklets; minor style/tsconfig tweaks

Written by Cursor Bugbot for commit 490ae19. Configure here.

@thomasttvo thomasttvo force-pushed the thomas/reanimated branch 3 times, most recently from 6251862 to 8e8b26f Compare December 24, 2025 06:10
# Conflicts:
#	src/ReactNativeZoomableView.tsx
@thomasttvo thomasttvo changed the base branch from thomas/functional to thomas/no-use-before-define December 24, 2025 21:15
Copy link
Collaborator

@elliottkember elliottkember left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking really great — amazing work. The performance gains from things like worklets will be out of this world.

We may need to make some minor changes in our app to implement this but they should be small fry compared to these changes.

disablePanOnInitialZoom?: boolean;

// Zoom animated value ref
zoomAnimatedValue?: Animated.Value;
Copy link
Collaborator

@elliottkember elliottkember Dec 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will probably be the tricky part in our internal implementation of this. I've never truly liked the way this component takes an animated value as a prop, this is how we ended up with sheet zoom contexts where other components need to know about zoom as it happens and we needed an HOC with the animated zoom value.

It seems like an imperative handle is probably the way to do this, plus maybe some built-in components for handling interpolations — or perhaps just a context provided by this component to its children.


const distance = calcGestureTouchDistance(e);

// TODO this gets called way too often, we need to find a better way
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah these kind of props sort of break the whole magic of reanimated and animated values huh?

Do we use this, or can we just subscribe to the animations and react with animated components?

I think this will maybe just be a huge major version release with lots of breaking changes that remove footguns

@thomasttvo thomasttvo marked this pull request as ready for review December 25, 2025 03:21
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment @cursor review or bugbot run to trigger another review on this PR

@thomasttvo
Copy link
Collaborator Author

bugbot run

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no bugs!


Comment @cursor review or bugbot run to trigger another review on this PR

@elliottkember
Copy link
Collaborator

I noticed that the example and base repos have different versions of reanimated. This is a good thing, I think — it shows that the library works on both versions. But when I went to refactor runOnJs to scheduleOnRN because of a deprecation warning in Reanimated 4, I noticed that it's only deprecated in the example app.

Might be worth using the same version in both... or maybe even having two example apps for testing both reanimateds at once??

~/Sites/react-native-zoomable-view elliott/thomas-reanimated-runonjs • yarn why react-native-reanimated |grep Found
=> Found "react-native-reanimated@3.16.7"
~/Sites/react-native-zoomable-view elliott/thomas-reanimated-runonjs • cd example && yarn why react-native-reanimated |grep Found
=> Found "react-native-reanimated@4.1.6"

elliottkember and others added 6 commits December 26, 2025 17:03
This is a new worklet function in Reanimated 4 that they want us to use

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Updates the example to use the new worklet scheduling utility.
> 
> - In `example/App.tsx`, replace
`runOnJS(debouncedUpdateMovePin)(position)` with
`scheduleOnRN(debouncedUpdateMovePin, position)` inside
`onStaticPinPositionMoveWorklet`
> - Add `scheduleOnRN` import from `react-native-worklets` and remove
`runOnJS` import from `react-native-reanimated`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
dae0226. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Comment on lines +134 to +142
<Button
// Toggle modal to test if zoomable view works correctly in modal,
// where pull-down-to-close gesture can interfere with pan gestures.
title={`Toggle Modal Mode`}
onPress={() => {
setModal((value) => !value);
}}
/>
</Wrapper>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clever! I think this should exhibit the same behaviour as the react-navigation / react-native-screens pull to close, but I might add the routing library and some formSheet / pageSheet routes just to test the theory

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥳 Looks good with expo-router, which uses native-stack under the hood!

image

@thomasttvo thomasttvo added breaking Breaking changes enhancement New feature or request labels Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaking changes enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants