oblador / react-native-animatable

Standard set of easy to use animations and declarative transitions for React Native
MIT License
9.85k stars 702 forks source link

Question: how to change text animated? #253

Open oferRounds opened 5 years ago

oferRounds commented 5 years ago

Tried to understand from the documents, but wasn’t able to...

How can I transition between two texts in animated way?

Thank you so much for this awesome library!

lalmachado commented 5 years ago

@oferRounds you can try something like this:

import React from 'react';
import * as Animatable from 'react-native-animatable';

class TransitionText extends React.Component {
  componentWillUpdate() {
    this.text.pulse(400);
  }

  handleTextRef = ref => this.text = ref;

  render() {
    const { children } = this.props;
    return (
      <Animatable.Text ref={this.handleTextRef} {...this.props}>
        {children}
      </Animatable.Text>
    );
  }
}

export default TransitionText;
oferRounds commented 5 years ago

@lalmachado thank you so much! I’ll try it!

iagormoraes commented 5 years ago

This doesn't change the text to another in animatable way, it just pulse and the text changes without animation, like fade out and fade in.

lalmachado commented 5 years ago

@iagorm you can add the animations you want on an imperative way in componentWillUpdate method like described here. The code above it is only an example on how to do that

iagormoraes commented 5 years ago

@lalmachado I was looking for a situation like this example:

https://cloud.githubusercontent.com/assets/219689/3491845/29bb0f8c-059e-11e4-9ef8-de56bec1baba.gif

Where there are two texts and they replace each other in a morph animation way.

BenHakimIlyass commented 2 years ago

Hey @iagormoraes, I now it's been 3 years now lol, but ok!!

I was just looking for a solution using Animated api from react-native, and ended up creating a new component that might be helpful for you.

function AnimatedText({ children: value, style, ...rest }) {
  const [localValue, setLocalValue] = React.useState(null);
  const fadeAnim = React.useRef(new Animated.Value(1)).current;

  const fadeIn = React.useCallback(
    (fn) => Animated.timing(fadeAnim, { toValue: 1, useNativeDriver: true }).start(fn),
    [fadeAnim],
  );
  const fadeOut = React.useCallback(
    (fn) => Animated.timing(fadeAnim, { toValue: 0, useNativeDriver: true }).start(fn),
    [fadeAnim],
  );
  const ease = React.useCallback(
    () => fadeOut(() => fadeIn(setLocalValue(value))),
    [value, fadeIn, fadeOut],
  );

  React.useEffect(() => {
    if (!localValue) { setLocalValue(value); return; }
    ease();
  }, [value, ease]);

  if (!localValue) { return null; }

  return (
    <Animated.Text style={StyleSheet.flatten([style, { opacity: fadeAnim }])} {...rest}>
      {localValue}
    </Animated.Text>
  );
}

Usage

Just like the normal Text component, pass a string a children and use all other Text props.

...

<AnimatedText>
  {text}
</AnimatedText>

...