Skip to content

Commit

Permalink
return final animation values to JS when animation completes (faceboo…
Browse files Browse the repository at this point in the history
…k#36731)

Summary:
Pull Request resolved: facebook#36731

When using the native driver for animations that involve layout changes (ie. translateY and other transforms, but not styles such as opacity), because it bypasses Fabric, the new coordinates are not updated so the Pressability responder region/tap target is incorrect

**This diff:**
- Returning the final values from the native side, at the same place it sets the "finished" flag. This gets sent to JS in `animated/animations/Animation.js`. In this diff I'm passing the value when 'hasFinishedAnimations' is true, but in a follow up diff I will look into other cases such as cancelled animations

Next:
2. Update the Animated.Value to reflect the new values
3. Call the onEnd function if there is one set
4. Use `setNativeProps` to pass the new values down for layout calculations and the correct Pressability responder region

Changelog:
[General][Changed] - return animated values to JS for natively driven animations

Reviewed By: javache

Differential Revision: D44110833

fbshipit-source-id: 3a2a24b5184836450beb5dc698db01253fe91437
  • Loading branch information
genkikondo authored and facebook-github-bot committed Jun 8, 2023
1 parent 108309e commit fdbfd9e
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ const parallel = function (
}

animations.forEach((animation, idx) => {
const cb = function (endResult: EndResult | {finished: boolean}) {
const cb = function (endResult: EndResult) {
hasEnded[idx] = true;
doneCount++;
if (doneCount === animations.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type {TurboModule} from '../TurboModule/RCTExport';
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
import shouldUseTurboAnimatedModule from './shouldUseTurboAnimatedModule';

type EndResult = {finished: boolean, ...};
type EndResult = {finished: boolean, value?: number, ...};
type EndCallback = (result: EndResult) => void;
type SaveValueCallback = (value: number) => void;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type {TurboModule} from '../TurboModule/RCTExport';
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
import shouldUseTurboAnimatedModule from './shouldUseTurboAnimatedModule';

type EndResult = {finished: boolean, ...};
type EndResult = {finished: boolean, value?: number, ...};
type EndCallback = (result: EndResult) => void;
type SaveValueCallback = (value: number) => void;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type AnimatedValue from '../nodes/AnimatedValue';

import NativeAnimatedHelper from '../NativeAnimatedHelper';

export type EndResult = {finished: boolean, ...};
export type EndResult = {finished: boolean, value?: number, ...};
export type EndCallback = (result: EndResult) => void;

export type AnimationConfig = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ private void stopAnimationsForNode(AnimatedNode animatedNode) {
// Invoke animation end callback with {finished: false}
WritableMap endCallbackResponse = Arguments.createMap();
endCallbackResponse.putBoolean("finished", false);
endCallbackResponse.putDouble("value", animation.mAnimatedValue.mValue);
animation.mEndCallback.invoke(endCallbackResponse);
} else if (mReactApplicationContext != null) {
// If no callback is passed in, this /may/ be an animation set up by the single-op
Expand All @@ -310,6 +311,7 @@ private void stopAnimationsForNode(AnimatedNode animatedNode) {
WritableMap params = Arguments.createMap();
params.putInt("animationId", animation.mId);
params.putBoolean("finished", false);
params.putDouble("value", animation.mAnimatedValue.mValue);
mReactApplicationContext.emitDeviceEvent(
"onNativeAnimatedModuleAnimationFinished", params);
}
Expand All @@ -332,6 +334,7 @@ public void stopAnimation(int animationId) {
// Invoke animation end callback with {finished: false}
WritableMap endCallbackResponse = Arguments.createMap();
endCallbackResponse.putBoolean("finished", false);
endCallbackResponse.putDouble("value", animation.mAnimatedValue.mValue);
animation.mEndCallback.invoke(endCallbackResponse);
} else if (mReactApplicationContext != null) {
// If no callback is passed in, this /may/ be an animation set up by the single-op
Expand All @@ -340,6 +343,7 @@ public void stopAnimation(int animationId) {
WritableMap params = Arguments.createMap();
params.putInt("animationId", animation.mId);
params.putBoolean("finished", false);
params.putDouble("value", animation.mAnimatedValue.mValue);
mReactApplicationContext.emitDeviceEvent(
"onNativeAnimatedModuleAnimationFinished", params);
}
Expand Down Expand Up @@ -645,6 +649,7 @@ public void runUpdates(long frameTimeNanos) {
if (animation.mEndCallback != null) {
WritableMap endCallbackResponse = Arguments.createMap();
endCallbackResponse.putBoolean("finished", true);
endCallbackResponse.putDouble("value", animation.mAnimatedValue.mValue);
animation.mEndCallback.invoke(endCallbackResponse);
} else if (mReactApplicationContext != null) {
// If no callback is passed in, this /may/ be an animation set up by the single-op
Expand All @@ -653,6 +658,7 @@ public void runUpdates(long frameTimeNanos) {
WritableMap params = Arguments.createMap();
params.putInt("animationId", animation.mId);
params.putBoolean("finished", true);
params.putDouble("value", animation.mAnimatedValue.mValue);
mReactApplicationContext.emitDeviceEvent(
"onNativeAnimatedModuleAnimationFinished", params);
}
Expand Down

0 comments on commit fdbfd9e

Please sign in to comment.