react-spring icon indicating copy to clipboard operation
react-spring copied to clipboard

[bug]: Animation works on Web, but crashes on iOS

Open joshuaellis opened this issue 2 years ago • 10 comments

Discussed in https://github.com/pmndrs/react-spring/discussions/1859

Originally posted by raarts March 11, 2022 Here's my codesandbox: https://codesandbox.io/s/toasters-independent-animation-ikp8e5?file=/src/App.tsx

This code runs fine on react native web. But on iOS it results in the following error.

https://user-images.githubusercontent.com/3168197/157865741-d06ced49-af5c-4395-a955-fbdb35534358.mov

It seems to be related to how to specify transforms on react native, and react-spring might be using a deprecated way of doing that. This is just speculation though.

@raarts this is a bug, so i've moved it here. We'd have to figure out a way for the interpolation methods to understand we're native not DOM based.

joshuaellis avatar Mar 11 '22 13:03 joshuaellis

In the mean time you could do a custom interpolation, can you share a small snippet of the spring and the element please?

joshuaellis avatar Mar 11 '22 13:03 joshuaellis

Joshua, thank you for your assistance, I have to admit I am an absolute beginner in animations. I'm note sure what you're asking me to do. Can you please explain? All code is in the sandbox, but maybe I misunderstand.

raarts avatar Mar 11 '22 15:03 raarts

So currently you're just passing the styles like so:

    <AnimatedView
      style={props}
    >

instead you can do a "custom interpolation" like this:

    /* this would only work in the web */
    <AnimatedView
      style={{
        opacity: props.opacity,
        transform: props.x.to((val) => `translate3D(${val}px, 0, 0)`)
      }}
    >

Where instead of what i've done with translate3D.... and checking out this example you could instead write it like props.x.to(val => [{translateX: val}])

You can see the interpolation in action here: https://codesandbox.io/s/toasters-independent-animation-forked-8s6l9e?file=/src/Toaster/ToasterBox.tsx:906-1055

joshuaellis avatar Mar 11 '22 15:03 joshuaellis

I see what you mean, and I have tried using translateX myself, but couldn't get it to work.

Your interpolation works on the web, but using translateX doesn't work on iOS:

Schermafbeelding 2022-03-11 om 5 36 32 PM

and typescript complains about it too:

Schermafbeelding 2022-03-11 om 5 33 09 PM

Actual code:

    <AnimatedView
      style={{
        transform: props.x.to((val) => {
          return [{ translateX: val }];
        }),
      }}
    >
      <View style={[styles.boxContainer, { backgroundColor }]}>
        <View style={styles.iconView}>{icon}</View>
        <View style={styles.textView}>
          <Text style={styles.textStyle}>{text}</Text>
        </View>
      </View>
    </AnimatedView>

raarts avatar Mar 11 '22 16:03 raarts

I wondered why transform would be typed as a string, and - smack on the forehead - changed:

import { animated, useSpring } from 'react-spring';

into

import { animated, useSpring } from '@react-spring/native';

and the typescript error went away, but alas, more iOS errors.

Then I reverted back to:

    <AnimatedView style={props}>

and bingo! No more crashes!

There are some problems left though.

First, is it really necessary to use different imports for web and native, because (almost) all of my code is shared between platforms. I can split it out if I have to using the Toaster.native.tsx vs Toaster.web.tsx trick.

Second problem is that the slide-in from the right stopped working, but that may have to do with different flexbox behaviour.

Really appreciate your support.

raarts avatar Mar 11 '22 17:03 raarts

II haven't been able to make the slide-in working on native. Also I have a weird Typescript error on native:

Schermafbeelding 2022-03-11 om 9 29 46 PM

It happen if I use import '@react-springs/native, which stops the app from crashing, but x animation doesn't work.

raarts avatar Mar 11 '22 20:03 raarts

I think you need to be using animated(View) where animated is imported from @react-spring/native if you're able to provide a github repo I can take a look? 😄

joshuaellis avatar Mar 12 '22 09:03 joshuaellis

Sure, here it is: https://github.com/raarts/example-with-react-spring-1860.git

raarts avatar Mar 13 '22 10:03 raarts

I encountered a similar problem, and got stuck for weeks.

I ended up modifying the suggestion above from:

style={{
  transform: props.x.to(val => [{translateX: val}])
}}

to (something like):

style={{
  transform: [
    {
      translateX: props.x.to((val) => val)
    }
  ]
}}

And it works (for my case).

xcoderreal avatar Jul 27 '22 06:07 xcoderreal

I have a similar problem trying to implement a scale animation:

const scaleAnimation = useSpring({
    from: {
      scale: 0,
    },
    to: {
      scale: 1,
    },
    config: {
      tension: 300,
    },
    reset: true,
  })

However, the above code only works in web:

<AnimatedView style={scaleAnimation}>
</AnimatedView>

for native I must use something like:

<AnimatedView style={{ transform: [{ scale: scaleAnimation.scale }] }}>
</AnimatedView>

ruida-shen avatar Feb 22 '23 21:02 ruida-shen