reactjs / react-transition-group

An easy way to perform animations when a React component enters or leaves the DOM
https://reactcommunity.org/react-transition-group/
Other
10.18k stars 649 forks source link

Trying to make an animation inside an animation doesn't work #138

Open alonbt opened 7 years ago

alonbt commented 7 years ago

I'm not sure if I'm using it wrong (then it's a bug) or am I trying to do something that is not possible (then it's a feature)

I'm trying basically to make an animation inside an animation. so when one item is fading, the child will scale:

     < Fade > {this.state.showNested &&
          < div >
              < div > I will fade < /div> 
              < div > 
                   < Scale > {
                        this.state.showNested && < div > I should scale < /div>}
                   </Scale >
              < /div> 
           < /div >} 
      < /Fade>

I've created this fiddle to demonstrate: https://jsfiddle.net/alonbt/8uL5c5hw/

I have there a Fade and a Scale components. when they are side by side they are working. but when I put the Scale inside the Fade - the Scale is not scaling.

I also added to the fiddle console.log to 'onEnter' and 'onExit' so it is visible that only one is being triggered and not twice as I wanted.

I know I can use a timeout and a different variable to activate each animation - but I'm trying to see if CSSTransition and TransitionGroup can somehow understand that there is a nested animation and execute it properly.

jquense commented 7 years ago

There are a few things a can suggest but first is there a reason for using the TransitionGroup vs the single CSSTransition by themselves? Is this ultimately going to be nested lists or single items nested

alonbt commented 7 years ago

I want to create a set of components such as Fade, Scale, Move, etc... (with more features) and that they can be combined independent or as nested elements. so if I will have a section in my project that I want to mount it will then move to the left but the button inside of it will scale (as an example)

For the scenario I am aiming for in my project I prefer it will look like this:

<TransitionGroup>  <-- Fade
   <CSSTransition>  <-- Fade
       <TransitionGroup> <-- Scale
             <CSSTransition>  <--Scale

but it can also be:

<TransitionGroup> <-- Parent
   <CSSTransition> <-- Fade
      <CSSTransition> <-- Scale

I must say I'm not 100% sure when/why to use the TransitionGroup twice and when to use it once. also, I'm aware there is an easy css solution, something like:

.fade-active .scale-child { ...scaling goes here... }

but I'm look for the pure Component solution so they will be easily combined as components

alonbt commented 7 years ago

I'm adding this example to show exactly what I want to achieve: https://jsfiddle.net/alonbt/8e56c5fn/

It's basically to do exactly this but without using 2 variables and all the setTimeouts

jquense commented 7 years ago

So the TransitionGroup is for animating lists of things. And Transition is for animating one thing. Generally you define a transition in terms of one item (e.g. this div fades in and out) and then you can use that with the TransitionGroup to define the animations for each item. So in your case i'm gonna assume the top level thing is you want to animate a list of items in, where each item fades and scales in.

https://jsfiddle.net/8uL5c5hw/7/

Gets you there HOWEVER I totally found a bug with the appear animations so you can see it's a bit broken (it scales out immediately)

Take a look thow at how Implemented it in a few composable components.

alonbt commented 7 years ago

Thanks for the help. looks like what I was missing is the 'in' prop. I wrote the code with this convention:

<Fade>{isShow && <div>my content</div>}</Fade>

which probably led to mount/unmount problems. using 'in' instead seemed to solve it. THANKS A LOT!!!