oblador / react-native-animatable

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

Rotation 180deg at event #219

Open Angelk90 opened 6 years ago

Angelk90 commented 6 years ago

Hi, @oblador: I'm trying to rotate a 180deg icon every time an event is executed. Link: https://snack.expo.io/rJoNufrwX Find it in BarCollapsible -> toggleView ()

I have to do this, the movement must be 180 deg each time. If I have to open the collapse, the movement must go from the bottom up to the left. If I have to collapse the collapse, the movement must go from top to bottom to the left.

Color must not change.

Where am I doing wrong?

perhapsJohn commented 6 years ago
const Animations = {
  rotate: {
    0: {
      rotate: '0deg',
      color: 'rgba(0,0,0,0.6)',
    },
    1: {
      rotate: '180deg',
      color: 'rgba(255, 87, 34, 0.5)',
    },
  },
};

Your animation specifies that the animation will always start at 0 degrees. This doesn't mean 0 degrees relative to it's current rotation, rather it will set the current rotation to 0 degrees and begin from there.

What you need is to animate from 0 to 180 degrees if your menu isn't showing, and rotate from 180 to 0 (or 360) degrees if the menu is showing. There are two ways I can think of that you can go about doing this.

One is to have two separate animations:

const Animations = {
  rotateDown: {
    0: {
      rotate: '0deg',
      color: 'rgba(0,0,0,0.6)',
    },
    1: {
      rotate: '180deg',
      color: 'rgba(255, 87, 34, 0.5)',
    },
  },
  rotateUp: {
    0: {
      rotate: '180deg',
      color: 'rgba(255, 87, 34, 0.5)',
    },
    1: {
      rotate: '360deg',
      color: 'rgba(0,0,0,0.6)',
    },
  },
};

And then in your toggleView just choose which animation to play based on show in your state:

toggleView = () => {
    const { show, iconCollapsed, iconOpened } = this.state;
    const animation = show ? 'rotateUp' : 'rotateDown';
    this.animatable.animate(animation, 1000);

    this.setState({
        show: !show,
        icon: show ? iconCollapsed : iconOpened,
    });
};

For reference: https://snack.expo.io/rJ-mLPBO7

Or you could use transition or transitionTo if you prefer not defining the animations. The transitionTo function will try to take the current style and animate to the specified style.

toggleView = () => {
    const { show, iconCollapsed, iconOpened } = this.state;
    this.animatable.transitionTo({ rotate: show ? '0deg' : '180deg' });

    this.setState({
        show: !show,
        icon: show ? iconCollapsed : iconOpened,
    });
};

With this there is no need to specify a custom animation, but just be sure to set the initial style on the element, otherwise it might not animate as you expect the first time.

For reference: https://snack.expo.io/HkQ6awBd7

I'm not certain what you want for the color. The first example has a smooth transition between the two states, and the second doesn't change again after the initial transition.

Hope this helps!