admin管理员组

文章数量:1287583

My current version is hiding each row, but it happens too quickly, as you can see here in my codepen. Repro by deleting the top element.

I would prefer if you the events unfolded like this:

  1. Fade out
  2. Slide up

I'm unsure how to do this using CSS transitions and the ReactTransitionGroup

If I can get to the stage that you see the element disappearing, then everything bunching up that would be a great start!!

My transition stuff:

const CustomerList = ({ onDelete, customers }) => {
  return (
    <div class="customer-list">
      <TransitionGroup>
        {customers.map((c, i) => 
          <CSSTransition
            key={i}
            classNames="customer"
            timeout={{ enter: 500, exit: 1200 }}
          >        
            <CustomerRow
              customer={c}
              onDelete={() => onDelete(i, c)}
            />
          </CSSTransition>
        )}  
      </TransitionGroup>
    </div>
  );
}

My CSS:

.customer-enter {
  opacity: 0.01;
}

.customer-enter.customer-enter-active {
  opacity: 1;
  transition: 500ms;
}

.customer-exit {
  opacity: 1;
}

.customer-exit.customer-exit-active {
  opacity: 0.01;
  transition: 1200ms;
}

Update

I've figured out with css you can have two transitions happening in sequence something like this

.something {

  width: 200px;
  height: 100px;
  background-color: black;

  transition: background-color 200ms ease, height 200ms ease 200ms;

}

.something:hover {
  height: 0px;
  background-color: blue;
}

So it is just a case of the <CSSTransition timeout={} /> actually waiting for it...

React Update

I have the "effect" working.... see codepen

But, obviously here, the elements still remain, which isn't the right functional behaviour

My current version is hiding each row, but it happens too quickly, as you can see here in my codepen. Repro by deleting the top element.

I would prefer if you the events unfolded like this:

  1. Fade out
  2. Slide up

I'm unsure how to do this using CSS transitions and the ReactTransitionGroup

If I can get to the stage that you see the element disappearing, then everything bunching up that would be a great start!!

My transition stuff:

const CustomerList = ({ onDelete, customers }) => {
  return (
    <div class="customer-list">
      <TransitionGroup>
        {customers.map((c, i) => 
          <CSSTransition
            key={i}
            classNames="customer"
            timeout={{ enter: 500, exit: 1200 }}
          >        
            <CustomerRow
              customer={c}
              onDelete={() => onDelete(i, c)}
            />
          </CSSTransition>
        )}  
      </TransitionGroup>
    </div>
  );
}

My CSS:

.customer-enter {
  opacity: 0.01;
}

.customer-enter.customer-enter-active {
  opacity: 1;
  transition: 500ms;
}

.customer-exit {
  opacity: 1;
}

.customer-exit.customer-exit-active {
  opacity: 0.01;
  transition: 1200ms;
}

Update

I've figured out with css you can have two transitions happening in sequence something like this

.something {

  width: 200px;
  height: 100px;
  background-color: black;

  transition: background-color 200ms ease, height 200ms ease 200ms;

}

.something:hover {
  height: 0px;
  background-color: blue;
}

So it is just a case of the <CSSTransition timeout={} /> actually waiting for it...

React Update

I have the "effect" working.... see codepen

But, obviously here, the elements still remain, which isn't the right functional behaviour

Share Improve this question edited Jul 25, 2017 at 13:52 Callum Linington asked Jul 25, 2017 at 12:55 Callum LiningtonCallum Linington 14.4k14 gold badges79 silver badges156 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 5

So, I asked this question on the Github repo for this library, and got a reply with a proper working version. Until the guy who responded posts an answer here, I want to share his answer.

Hi there, you have two issues with the codepen. The first is you aren't using a stable key for your list items, so removing something in the middle of the list won't work right. The second is that your setup is correct, and the timeout is working and the animation is playing, but you don't see the animation for height play because you can't animate from height: auto with plain css transitions.

here https://codepen.io/anon/pen/dzPvEO?editors=0110 is a working pen but it requires setting an explicit hieght on the items (max-height isn't enough). One way of dealing with this neatly in a dynamic manner is to use the onExit callback to measure and set the height on the exiting item so it has an explicit height set while exiting

So the first thing was setting a more consistent key property value:

<CSSTransition
    key={c.name}
    classNames="customer"
    timeout={{ enter: 500, exit: 700 }}
>        
    <CustomerRow
        customer={c}
        onDelete={() => onDelete(i, c)}
    />
</CSSTransition>

Secondly was to make sure I set a height on the containing div class.

Is this better? I used keyframes:

.customer-exit {
  opacity: 0;
  /*transition: opacity 300ms ease, height 400ms ease 300ms;*/
      -webkit-animation: slideIn 0.7s ease;forwards;
    -moz-animation: slideIn 0.7s ease;
    animation: slideIn 0.7s ease;
}

.customer-exit.customer-exit-active {
  opacity: 0.01;
  height: 0px;
}

@keyframes slideIn {
    0% {
       opacity:1
    }

      50% {
       opacity:0
    }
       90% {
       transform: translate(0,-100px);
    }
    100% {
      opacity:0
        /*transform: translateY(0px);*/
        /*opacity:1*/
    }
}

https://codepen.io/vladop/pen/PKwmMg

I wanted to share a recent library that solves these types of problems very easily and intuitively, called React Sequencer.

The library is similar to ReactCSSTransition only it gives you full control over the stages of sequences and their durations. I have made an example that solves your problem here:

https://codesandbox.io/s/nrw3261m20

What's nice is that the solution doesn't require any repaint hacks or clunky callbacks - but performs the animation just by giving you state and letting you render the state you like.

The example shows how you could use it to fade an element out, and then collapse it as a second step in the sequence, making for a very smooth looking animation.

What I would do in this case is to separate the animations out into two separate ones.
- Each item would animate themselves in/out
- The "Y" position of each item would be calculated based on its position in the list (e.g. 0, 1, 2, 3, 4 etc), which can be passed in from the list

This way once, say, the 1st item finishes animating itself out, the list would be updated so the items previously in the 2nd, 3rd, and 4th rows would now be told they're in the 1st, 2nd, and 3rd row, and have a new Y position they should be in, and transition to those new Y positions

I would remend looking at react-motion for transitioning on the Y

本文标签: javascriptReact Transition Group slide elements upStack Overflow