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

SharedValue is an type of object, and sometimes a number #6000

Open
Michota opened this issue May 9, 2024 · 5 comments
Open

SharedValue is an type of object, and sometimes a number #6000

Michota opened this issue May 9, 2024 · 5 comments
Labels
Missing repro This issue need minimum repro scenario Platform: Android This issue is specific to Android

Comments

@Michota
Copy link

Michota commented May 9, 2024

Description

I got following bug:

Invariant Violation: Transform with key of "translateX" must be a number: {"translateX":{"onFrame":{},"onStart":{},"toValue":168.21428571428572,"velocity":10.531789498949639,"current":164.5932737384055,"startValue":164.64457455258392,"lastTimestamp":13514092.617269,"startTimestamp":13513334,"zeta":0.5,"omega0":10,"omega1":8.660254037844386,"reduceMotion":false,"callStart":null,"timestamp":13514092.617269}}

This error is located at:
...

When I started to investigate what is the reason that it appears, i stumbled upon this weird behavior or SharedValue inside useAnimatedStyle: value is an object, but it should be a primitive (a number).

   const dislikeButtonStartPosition = useSharedValue({
      x: DISLIKE_BUTTON_START_POSITION.x,
      y: windowDimensions.height - 100,
    });
    const dislikeButtonOffset = useSharedValue({
      x: dislikeButtonStartPosition.value.x,
      y: dislikeButtonStartPosition.value.y,
    });
    const curtainOffset = useSharedValue(0);
    const curtainWidth = useSharedValue(0);

    const dislikeButtonSize = useSharedValue(DISLIKE_BUTTON_SIZE);

    console.log(dislikeButtonOffset.value.x, dislikeButtonOffset.value.y); // THERE THEY ARE LOGGED AS NUMBER

    const dislikeButtonAnimatedStyles = useAnimatedStyle(() => {
      console.log(dislikeButtonOffset.value.x, dislikeButtonOffset.value.y); // THERE THEY ARE LOGGED AS OBJECT

      return {
        backgroundColor: "red",
        position: "absolute",
        justifyContent: "center",
        alignItems: "center",
        borderRadius: 100,
        width: dislikeButtonSize.value,
        height: dislikeButtonSize.value,
        transform: [
          { translateX: dislikeButtonOffset.value.x },
          { translateY: dislikeButtonOffset.value.y },
          { scale: withSpring(isDislikeButtonHidden.value ? 0 : 1) },
        ],
      };
    });

When i log dislikeButtonOffset.value.x in console, i get

{
callStart: null
callback: undefined
current: 164.919688
lastTimestamp: 14029578.333438
omega0: 10
omega1: 8.660254
onFrame: {}
onStart: {}
reduceMotion: false
startTimestamp: 14028901
startValue: 93.168546
timestamp: 14029578.333438
toValue: 168.214286
velocity: -22.668363
zeta: 0.5
}

It wasn't like that a month ago, so i guess it has something to do with new version of react-native-reanimated.

Steps to reproduce

Described in previous section.

Snack or a link to a repository

I cant provide this, its a private project.

Reanimated version

3.10.1

React Native version

0.74.1

Platforms

Android

JavaScript runtime

Hermes

Workflow

Expo Dev Client

Architecture

Paper (Old Architecture)

Build type

Debug app & dev bundle

Device

Real device

Device model

Oneplus 9pro

Acknowledgements

Yes

@github-actions github-actions bot added Missing repro This issue need minimum repro scenario Platform: Android This issue is specific to Android labels May 9, 2024
Copy link

github-actions bot commented May 9, 2024

Hey! 👋

The issue doesn't seem to contain a minimal reproduction.

Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?

@szydlovsky
Copy link
Contributor

Hey @Michota would you be able to provide a minimal reproduction that contains the problem? Your example is quite complicated. Also, looking at the code I can tell at least one thing that is not completely fine: dislikeButtonOffset won't be a reactive shared value, because you create it depending on other shared value. I'd suggest using useDerivedValue in such situation.

@Michota
Copy link
Author

Michota commented May 21, 2024

Can you tell me why does this work? For some reason derivedValue as an object does not work, but it does work as two values.

    const dislikeButtonOffset = useSharedValue({
      x: dislikeButtonStartPosition.value.x,
      y: dislikeButtonStartPosition.value.y,
    });
    const curtainOffset = useSharedValue(0);
    const curtainWidth = useSharedValue(0);

    const dislikeButtonOffsetX = useDerivedValue(() => dislikeButtonOffset.value.x);
    const dislikeButtonOffsetY = useDerivedValue(() => dislikeButtonOffset.value.y);

    const dislikeButtonSize = useSharedValue(DISLIKE_BUTTON_SIZE);

    const dislikeButtonAnimatedStyles = useAnimatedStyle(() => {
      return {
        backgroundColor: "yellow",
        position: "absolute",
        justifyContent: "center",
        alignItems: "center",
        borderRadius: 100,
        width: dislikeButtonSize.value,
        height: dislikeButtonSize.value,
        transform: [
          { translateX: dislikeButtonOffsetX.value },
          { translateY: dislikeButtonOffsetY.value },    

But this does not?

 const dislikeButtonOffset = useSharedValue({
      x: dislikeButtonStartPosition.value.x,
      y: dislikeButtonStartPosition.value.y,
    });
    const curtainOffset = useSharedValue(0);
    const curtainWidth = useSharedValue(0);

    const dislikeButtonOffsetTwo = useDerivedValue(() => dislikeButtonOffset.value);

    const dislikeButtonSize = useSharedValue(DISLIKE_BUTTON_SIZE);

    const dislikeButtonAnimatedStyles = useAnimatedStyle(() => {
      return {
        backgroundColor: "yellow",
        position: "absolute",
        justifyContent: "center",
        alignItems: "center",
        borderRadius: 100,
        width: dislikeButtonSize.value,
        height: dislikeButtonSize.value,
        transform: [
          { translateX: dislikeButtonOffsetTwo.value.x },
          { translateY: dislikeButtonOffsetTwo.value.y },

@Michota
Copy link
Author

Michota commented May 21, 2024

Btw. changing dislikeButtonOffset to derived value will allow me to change its values in different functions, like this one?
Currently I am animating this in following way:

    const curtainShrinkRight = useCallback(() => {
      runOnUI(() => {
        isDislikeButtonHidden.value = false;

        dislikeButtonOffset.value = {
          x: withTiming(dislikeButtonStartPosition.value.x, {
            duration: 0,
          }),
          y: withTiming(dislikeButtonStartPosition.value.y, {
            duration: 0,
          }),
        };
      })();

      curtainOffset.value = withTiming(0, {
        duration: DISLIKE_CURTAIN_TIME.shrink,
      });

      curtainWidth.value = withTiming(0, {
        duration: DISLIKE_CURTAIN_TIME.shrink,
      });
    }, [
      curtainOffset,
      curtainWidth,
      dislikeButtonOffset,
      isDislikeButtonHidden,
      dislikeButtonStartPosition.value.x,
      dislikeButtonStartPosition.value.y,
    ]);

// some skipped code...

    useEffect(() => {
      if (isExpanded === false) {
        curtainShrinkRight();
      }
    }, [isExpanded, curtainShrinkRight]);

How do i modify it? Using modify() does not work, maybe I dont understand something...

@Michota
Copy link
Author

Michota commented May 21, 2024

May this be related to fact, that animations are being run in UI thread?

    const curtainExpandRight = useCallback(() => {
      curtainWidth.value = withTiming(screenDimensions.width / 2, {
        duration: DISLIKE_CURTAIN_TIME.expand,
      });

      curtainOffset.value = withDelay(
        DISLIKE_CURTAIN_TIME.expand,
        withTiming(
          0,
          {
            duration: DISLIKE_CURTAIN_TIME.expand,
          },
          () => {
            runOnJS(onCurtainExpand)();
            isDislikeButtonHidden.value = true;
          }
        )
      );
    }, [curtainOffset, curtainWidth, screenDimensions.width, onCurtainExpand, isDislikeButtonHidden]);

    const curtainShrinkRight = useCallback(() => {
      runOnUI(() => {
        isDislikeButtonHidden.value = false;

        dislikeButtonOffset.value = {
          x: withTiming(dislikeButtonStartPosition.x, {
            duration: 0,
          }),
          y: withTiming(dislikeButtonStartPosition.y, {
            duration: 0,
          }),
        };
      })();
      

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Missing repro This issue need minimum repro scenario Platform: Android This issue is specific to Android
Projects
None yet
Development

No branches or pull requests

2 participants