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
This commit is contained in:
Genki Kondo
2023-06-09 15:09:58 -07:00
committed by Facebook GitHub Bot
parent c5e0e2d169
commit 51cea49be7
@@ -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;