Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Natively driven translation transforms using Animated.Value expected results do not match JS driven if initialValue is non-zero #13452

Open
slswalker opened this issue Jul 16, 2024 · 1 comment
Assignees
Labels
Area: Animation bug Old Architecture Broad category for issues that apply to the RN "old" architecture of Cxx Modules + Paper Partner: Microsoft
Milestone

Comments

@slswalker
Copy link
Contributor

Problem Description

There are a few bugs at play, though all possibly caused by the same issue. When attempting to use natively driven Animated.Value to transform and translate a view from a non-zero starting point, the view is rendered in the incorrect location. With work arounds we can get this to work, but there is then a further bug. If the transform value needs to be modified before or after an animation, setValue cannot be called on the Value instance. Furthermore, to fix this we can opt-out of Composition native animation, but there is no publically available way to create an Animated.Value instance starting as a natively driven non-composition value.

So to summarize the three bugs.

  1. Animated.Value cannot be create with a non-zero value and be natively driven
  2. Animated.Value cannot have setValue called when natively driven
  3. new Animated.Value(initialValue, { useNativeDriver: true, platformConfig: { useComposition: false }}) will not pass the platform config down to native. This appears to be due to React Native's AnimatedValue constructor calling __makeNative() with no params unlike other Animated variants that do pass in the platform config.

Steps To Reproduce

First bug:

  1. Create a natively driven animated value with a non-zero initialValue. const translateYValue= useAnimatedValue(100, { useNativeDriver: true };
  2. Use this value on an Animated.View style transform: <Animated.View style={{ transform: [{ translateY: translateYValue }] }}/>

Second bug:

  1. Create a natively driven animated value with a zero initialValue. const translateYValue= useAnimatedValue(0, { useNativeDriver: true };
  2. On mount, set the value to anything else useEffect(() => translateYValue.setValue(100), []);

Third bug:

1. const translateYValue = useAnimatedValue(0, { useNativeDriver: true, platformConfig: { useComposition: false }});

Expected Results

Bug #1: Value performs like JS or non-composition animation. As a developer, I can use animated values that have a non-zero initial value

Bug #2: Value performs like JS or non-composition animation. As a developer, I can set the instance's value at any point while mounted to change the value natively

Bug #3: I have a way to turn off composition animation per animated node. Instead, I have to use a hidden function __setPlatformConfig.

CLI version

12.3.6, 13.6.8

Environment

I have reproduced this in two environments.

React Native 73 App

System:
  OS: Windows 11 10.0.22631
  CPU: (24) x64 13th Gen Intel(R) Core(TM) i7-13700K
  Memory: 35.61 GB / 63.70 GB
Binaries:
  Node:
    version: 20.15.1
    path: C:\Program Files\nodejs\node.EXE
  Yarn:
    version: 1.22.19
    path: C:\Program Files (x86)\Yarn\bin\yarn.CMD
  npm:
    version: 10.7.0
    path: C:\Program Files\nodejs\npm.CMD
  Watchman: Not Found
SDKs:
  Android SDK: Not Found
  Windows SDK:
    AllowDevelopmentWithoutDevLicense: Enabled
    AllowAllTrustedApps: Enabled
    Versions:
      - 10.0.18362.0
      - 10.0.19041.0
      - 10.0.22621.0
IDEs:
  Android Studio: Not Found
  Visual Studio:
    - 17.10.35027.167 (Visual Studio Enterprise 2022)
Languages:
  Java: Not Found
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.73.7
    wanted: 0.73.7
  react-native-windows:
    installed: 0.73.11
    wanted: 0.73.11
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found


React Native 74 Default App
System:
  OS: Windows 11 10.0.22631
  CPU: (24) x64 13th Gen Intel(R) Core(TM) i7-13700K
  Memory: 35.69 GB / 63.70 GB
Binaries:
  Node:
    version: 20.15.1
    path: C:\Program Files\nodejs\node.EXE
  Yarn:
    version: 3.6.4
    path: C:\Program Files (x86)\Yarn\bin\yarn.CMD
  npm:
    version: 10.7.0
    path: C:\Program Files\nodejs\npm.CMD
  Watchman: Not Found
SDKs:
  Android SDK: Not Found
  Windows SDK:
    AllowDevelopmentWithoutDevLicense: Enabled
    AllowAllTrustedApps: Enabled
    Versions:
      - 10.0.18362.0
      - 10.0.19041.0
      - 10.0.22621.0
IDEs:
  Android Studio: Not Found
  Visual Studio:
    - 17.10.35027.167 (Visual Studio Enterprise 2022)
Languages:
  Java: Not Found
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.74.2
    wanted: 0.74.2
  react-native-windows:
    installed: 0.74.9
    wanted: 0.74.9
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

Community Modules

No response

Target Platform Version

None

Target Device(s)

Desktop

Visual Studio Version

Visual Studio 2022

Build Configuration

Release

Snack, code example, screenshot, or link to a repository

The white box is where the content is positioned without a transform, the red box is where they are supposed to be after the transform is applied.

export function AnimationExampleSimple() {
  const transformYValueJS = useAnimatedValue(100);
  const transformYValueComposite = useAnimatedValue(100, {
    useNativeDriver: true,
  });

  return (
    <View
      style={[
        StyleSheet.absoluteFill,
        {justifyContent: 'center', alignItems: 'center'},
      ]}>
      <View
        style={{
          flexDirection: 'row',
          height: 100,
          width: 210,
          justifyContent: 'space-between',
          borderWidth: 2,
          borderColor: 'white',
        }}>
        <Animated.View
          style={{
            transform: [{translateY: transformYValueJS}],
            width: 100,
            height: 100,
            backgroundColor: 'green',
          }}
        />
        <Animated.View
          style={{
            transform: [{translateY: transformYValueComposite}],
            width: 100,
            height: 100,
            backgroundColor: 'blue',
          }}
        />
      </View>
      <View
        style={{height: 100, width: 210, borderWidth: 2, borderColor: 'red'}}
      />
    </View>
  );
}
@slswalker slswalker added the bug label Jul 16, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs: Triage 🔍 New issue that needs to be reviewed by the issue management team (label applied by bot) label Jul 16, 2024
@slswalker
Copy link
Contributor Author

For anyone that needs a workaround, here is a modified version of useAnimatedValue.

type PlatformConfig = {
    useComposition?: boolean;
};

type AnimatedValueConfig = Animated.AnimatedConfig & {
    platformConfig?: PlatformConfig;
};

type AnimatedValueWithPrivateFunctions = Animated.Value & {
    __setPlatformConfig(config?: PlatformConfig): void;
};

function useAnimatedValue(
    initialValue: number,
    config?: AnimatedValueConfig,
): Animated.Value {
    const ref = useRef<null | Animated.Value>(null);
    if (ref.current == null) {
        ref.current = new Animated.Value(initialValue, config);

        if (config && "platformConfig" in config) {
            (ref.current as AnimatedValueWithPrivateFunctions).__setPlatformConfig(config.platformConfig);
        }
    }

    return ref.current;
}

@chrisglein chrisglein added Area: Animation Partner: Microsoft Old Architecture Broad category for issues that apply to the RN "old" architecture of Cxx Modules + Paper labels Jul 16, 2024
@chrisglein chrisglein added this to the Next milestone Jul 22, 2024
@chrisglein chrisglein removed the Needs: Triage 🔍 New issue that needs to be reviewed by the issue management team (label applied by bot) label Jul 22, 2024
@chrisglein chrisglein modified the milestones: Next, Backlog Sep 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Animation bug Old Architecture Broad category for issues that apply to the RN "old" architecture of Cxx Modules + Paper Partner: Microsoft
Projects
None yet
Development

No branches or pull requests

2 participants