From 51cea49be73250f5b346db9882a2da522cd508d8 Mon Sep 17 00:00:00 2001 From: Genki Kondo Date: Fri, 9 Jun 2023 15:09:58 -0700 Subject: [PATCH] Sync AnimatedValue JS node value when animation completes (#37779) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37779 For natively driven animations, we now get the final value of the animation on JS side in the animation end callback. We sync this value into the JS-side AnimatedValue node. Changelog: [General][Changed] - Sync AnimatedValue JS node value when animation completes Differential Revision: D46498320 fbshipit-source-id: 550a3bbbd5323f917c175801b6414a721aa69be5 --- .../Libraries/Animated/animations/Animation.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/react-native/Libraries/Animated/animations/Animation.js b/packages/react-native/Libraries/Animated/animations/Animation.js index d71a86b5137d7d..6a14a87fabde3e 100644 --- a/packages/react-native/Libraries/Animated/animations/Animation.js +++ b/packages/react-native/Libraries/Animated/animations/Animation.js @@ -37,6 +37,7 @@ export default class Animation { __nativeId: number; __onEnd: ?EndCallback; __iterations: number; + start( fromValue: number, onUpdate: (value: number) => void, @@ -44,22 +45,26 @@ export default class Animation { previousAnimation: ?Animation, animatedValue: AnimatedValue, ): void {} + stop(): void { if (this.__nativeId) { NativeAnimatedHelper.API.stopAnimation(this.__nativeId); } } + __getNativeAnimationConfig(): any { // Subclasses that have corresponding animation implementation done in native // should override this method throw new Error('This animation type cannot be offloaded to native'); } + // Helper function for subclasses to make sure onEnd is only called once. __debouncedOnEnd(result: EndResult): void { const onEnd = this.__onEnd; this.__onEnd = null; onEnd && onEnd(result); } + __startNativeAnimation(animatedValue: AnimatedValue): void { const startNativeAnimationWaitId = `${startNativeAnimationNextId}:startAnimation`; startNativeAnimationNextId += 1; @@ -74,8 +79,17 @@ export default class Animation { this.__nativeId, animatedValue.__getNativeTag(), config, - // $FlowFixMe[method-unbinding] added when improving typing for this parameters - this.__debouncedOnEnd.bind(this), + result => { + this.__debouncedOnEnd(result); + + // When using natively driven animations, once the animation completes, + // we need to ensure that the JS side nodes are synced with the updated + // values. + const {value} = result; + if (value != null) { + animatedValue.__onAnimatedValueUpdateReceived(value); + } + }, ); } catch (e) { throw e;