jyurek
jyurek

Reputation: 1177

How can I index into an array using an Animated Value in React Native?

In React Native, if I have an Animated.Value that I want to animate from 0 to, say, 49.

const animatedValue = new Animated.Value(0)
const animate = () => {
  animatedValue.setValue(0)
  Animated.timing(animatedValue, {
    toValue:  49,
    duration: 1000,
  }).start()
}

And I have an array with 50 elements (for the example, let's say the names of the 50 US states)

const states = ["Alabama", ..., "Wyoming"]

Is there a way for me to display the value of the "current" index of the array in a component? For example, I want something like this, although this does not work:

<Pressable onPress={animate}>
  <Text>{states[Math.floor(animatedValue)]}</Text>
</Pressable>

I want that to cycle through the list of states (settling on Wyoming, as it's last) when I press the Pressable. It feels like there should be a way I can do this, although I can't seem to find one.

Upvotes: 2

Views: 1252

Answers (3)

Sachin Saini
Sachin Saini

Reputation: 401

For the function components:-

I am writing a function hopefully it will help you display a looping text with the animation

We will use this package for the animation https://github.com/oblador/react-native-animatable.

import {StyleSheet} from 'react-native';
import React, {useState} from 'react';
import * as Animatable from 'react-native-animatable';

const UserMessage = () => {
  const [index, setIndex] = useState(0);

  const meditations = [
    'Take a deep breath',
    'embrace this feeling',
    'breath deeply',
   ];
return (
<Animatable.Text
  key={index}
  animation={'fadeIn'}
  iterationCount={2}
  direction="alternate"
  duration={2000}
  onAnimationEnd={() => {
    if (index < meditations.length - 1) {
      setIndex(index + 1);
    } else {
      setIndex(0);
    }
  }}
  style={styles.messageStyle}>
  {meditations[index]}
</Animatable.Text>
);
};

export default UserMessage;

const styles = StyleSheet.create({
 messageStyle: {
textAlign: 'center',
fontSize: 18,
fontWeight: '500',
width: '80%',
color: '#1C1C1C',
marginBottom: 20,
minHeight: 50,
alignSelf: 'center',
},
});

Upvotes: 0

Sehrish Waheed
Sehrish Waheed

Reputation: 1565

Suppose you want to animate a list firstly give value

 const transformView = useRef(new Animated.ValueXY({ x: 0, y: 0 })).current;

After start bring it back to the initial position to start from there for other animations

Animated.timing(receiverRef, {
  toValue: { x: 500, y: 0 },
  duration: 500,
  useNativeDriver: true,
}).start(() => {
  LayoutAnimation.spring();
  Animated.timing(receiverRef, {
    toValue: { x: 0, y: 0 },
    duration: 500,
    useNativeDriver: true,
  })
});

Now to properly animate a specific index position View

transform: [
      {
         translateX:
                listid == indexToAnimate? transformView.x : 0,
       },
       {
         translateY:
               listid == indexToAnimate? transformView.y : 0,
        },
    ],

Upvotes: 1

jyurek
jyurek

Reputation: 1177

I was able to introspect on the value using addListener to the Animated.Value

const [usState, setUsState] = React.useState("Texas")
React.useEffect(() => {
  animatedValue.addListener(({value}) => {
    const index = Math.floor(value)
    setUsState(states[index])
  })
  return () => animatedValue.removeAllListeners()
}

And then when I call animate(), the Text component will iterate through the list of US States.

It feels like this isn't ideal, but it works.

Upvotes: 1

Related Questions