All Projects → marnusw → React Css Transition Replace

marnusw / React Css Transition Replace

Licence: mit
A React component to animate replacing one element with another.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to React Css Transition Replace

SPStorkController
Now playing controller from Apple Music, Mail & Podcasts Apple's apps.
Stars: ✭ 2,515 (+773.26%)
Mutual labels:  transition
state-workflow
State Workflow Management Package For Laravel. Inspired by ROAM Horizon State Management Package.
Stars: ✭ 29 (-89.93%)
Mutual labels:  transition
Sheet
📑 Actionsheet with navigation features such as the Flipboard App
Stars: ✭ 264 (-8.33%)
Mutual labels:  transition
react-transition-box
React component for easily transitioning your container size based on children 🎁
Stars: ✭ 13 (-95.49%)
Mutual labels:  transition
d3-canvas-transition
transition on canvas with d3
Stars: ✭ 19 (-93.4%)
Mutual labels:  transition
vue-smooth-height
Transition an elements height in response to data changes
Stars: ✭ 40 (-86.11%)
Mutual labels:  transition
angular-super-gallery
AngularJS super image gallery
Stars: ✭ 46 (-84.03%)
Mutual labels:  transition
Gtsheet
An easy to integrate solution for presenting UIViewControllers in a bottom sheet
Stars: ✭ 282 (-2.08%)
Mutual labels:  transition
ng-ionic-connectedanim
Connected Animation (Shared Element Transition) for Ionic Framework.
Stars: ✭ 12 (-95.83%)
Mutual labels:  transition
Guillotinemenu Android
Neat library, that provides a simple way to implement guillotine-styled animation
Stars: ✭ 2,743 (+852.43%)
Mutual labels:  transition
react-gizmo
🦎 React Gizmo - UI Finite State Machine for React
Stars: ✭ 39 (-86.46%)
Mutual labels:  transition
AppleMusicTransition
AppleMusic Transition playBar -> playDetail
Stars: ✭ 21 (-92.71%)
Mutual labels:  transition
Youtube-Pagination-ProgressBar
Youtube app uses a nice ProgressBar for pagiantion.The ProgressBar goes down using transition and then dissapear when the process ends,so I created a Custom ProgresBar as youtube app has.
Stars: ✭ 25 (-91.32%)
Mutual labels:  transition
unity-ui-manager
🎫 A Simple UI Manager for rapid prototyping and ease of collaboration
Stars: ✭ 44 (-84.72%)
Mutual labels:  transition
Samuraitransition
SamuraiTransition is an open source Swift based library providing a collection of ViewController transitions featuring a number of neat “cutting” animations.
Stars: ✭ 269 (-6.6%)
Mutual labels:  transition
vue2-animate
A port of Animate.css for use with transitions in Vue.js 2.0 / 3.0 and Alpine.js.
Stars: ✭ 1,338 (+364.58%)
Mutual labels:  transition
dsim.cljc
Idiomatic and purely functional discrete event-simulation
Stars: ✭ 81 (-71.87%)
Mutual labels:  transition
Viewpagertransition
viewpager with parallax pages, together with vertical sliding (or click) and activity transition
Stars: ✭ 3,017 (+947.57%)
Mutual labels:  transition
Swipetransition
Allows trendy transitions using swipe gesture such as "swipe back anywhere".
Stars: ✭ 272 (-5.56%)
Mutual labels:  transition
Transitionexample
a demo of Transition Framework
Stars: ✭ 257 (-10.76%)
Mutual labels:  transition

React CSS Transition Replace

A React component to animate replacing one element with another.

While ReactCSSTransitionGroup does a great job of animating changes to a list of components and can even be used to animate the replacement of one item with another, proper handling of the container height in the latter case is not built in. This component is designed to do exactly that with an API closely following that of ReactCSSTransitionGroup.

Using react-css-transition-replace provides two distinct benefits:

  • It automatically handles the positioning of the animated components, and
  • allows changes in the height of container to be handled and animated with ease when various content heights differ, even when absolute positioning is used.

Animations are fully configurable with CSS, including having the entering component wait to enter until the leaving component's animation completes. Following suit with the React.js API the one caveat is that the transition duration must be specified in JavaScript as well as CSS.

Live Examples | Change Log | Upgrade Guide

Installation

Install via npm:

npm install --save react-css-transition-replace

Usage

A ReactCSSTransitionReplace component can only have a single child. Other than that, the basic usage follows the exact same API as ReactCSSTransitionGroup, with support for transitionEnter, transitionLeave and transitionAppear. When the key of the child component changes, the previous component is animated out and the new component animated in. During this process:

  • All leaving components continue to be rendered; if the animation is slow there may be multiple components in the process of leaving.
  • The entering component is positioned on top of the leaving component(s) with absolute positioning.
  • The height of the container is set to that of the leaving component, and then immediately to that of the entering component. If the transitionName is a String the {animation-name}-height class name is applied to it, and if transitionName is an Object the transitionName.height class will be used if present.
  • The leaving component will be passed an isLeaving prop while transitioning out.

This provides many possibilities for animating the replacement as illustrated in the examples below.

Additionally, the boolean property changeWidth can be used to animate changing the width of the component. This change will happen at the same time as changing the height. Animating this change should be done using the same class name as is used for animating the change in height.

It is also possible to remove the child component (i.e. leave ReactCSSTransitionReplace with no children) which will animate the height going to zero along with the leave transition. Similarly, a single child can be added to an empty ReactCSSTransitionReplace, triggering the inverse animation.

By default a span is rendered as a wrapper of the child components. Each child is also wrapped in a span used in the positioning of the actual rendered child. These can be overridden with the component and childComponent props respectively.

Cross-fading two components

The ReactCSSTransitionReplace component is used exactly like its ReactCSSTransitionGroup counterpart:

import ReactCSSTransitionReplace from 'react-css-transition-replace';

render() {
  return (
    <ReactCSSTransitionReplace transitionName="cross-fade"
                               transitionEnterTimeout={1000} transitionLeaveTimeout={1000}>
      <SomeComponent key="uniqueValue"/>
    </ReactCSSTransitionReplace>
  );
}

To realize cross-fading of two components all that remains is to define the enter and leave opacity transitions in the associated CSS classes:

.cross-fade-leave {
  opacity: 1;
}
.cross-fade-leave.cross-fade-leave-active {
  opacity: 0;
  transition: opacity 1s ease-in;
}

.cross-fade-enter {
  opacity: 0;
}
.cross-fade-enter.cross-fade-enter-active {
  opacity: 1;
  transition: opacity 1s ease-in;
}

.cross-fade-height {
  transition: height 0.5s ease-in-out;
}

Note the additional .cross-fade-height class. This indicates how the container height is to be animated if the heights of the entering and leaving components are not the same. You can see this in action here.

Fade out, then fade in

To fade a component out and wait for its transition to complete before fading in the next, simply add a delay to the enter transition.

.fade-wait-leave {
  opacity: 1;
}
.fade-wait-leave.fade-wait-leave-active {
  opacity: 0;
  transition: opacity 0.4s ease-in;
}

.fade-wait-enter {
  opacity: 0;
}
.fade-wait-enter.fade-wait-enter-active {
  opacity: 1;
  /* Delay the enter animation until the leave completes */
  transition: opacity 0.4s ease-in 0.6s;
}

.fade-wait-height {
  transition: height 0.6s ease-in-out;
}

Note: The transitionEnterTimeout specified in the JS must be long enough to allow for the delay and the duration of the transition. In this case:

<ReactCSSTransitionReplace transitionName="fade-wait"
                           transitionEnterTimeout={1000} transitionLeaveTimeout={400}>

See the live example here.

React-Router v4

Animated transitions of react-router v4 routes is supported with two caveats shown in the example below:

  1. The current location must be applied to the Switch to force it to maintain the previous matched route on the leaving component.
  2. If the Switch might render null, i.e. there is no catch-all "*" route, the Switch must be wrapped in a div or similar for the leave transition to work; if not the previous component will disappear instantaneously when there is no match.
<Router>
  <div className="router-example">
    <ul>
      <li>
        <Link to="/">Home</Link>
      </li>
      <li>
        <Link to="/one">One</Link>
      </li>
      <li>
        <Link to="/two">Two</Link>
      </li>
      <li>
        <Link to="/three">Three (no match)</Link>
      </li>
    </ul>
    <Route
      render={({ location }) => (
        <ReactCSSTransitionReplace
          transitionName="fade"
          transitionEnterTimeout={500}
          transitionLeaveTimeout={500}
        >
          <div key={location.pathname}>
            <Switch location={location}>
              <Route path="/" exact component={Home} />
              <Route path="/one" component={One} />
              <Route path="/two" component={Two} />
            </Switch>
          </div>
        </ReactCSSTransitionReplace>
      )}
    />
  </div>
</Router>

See the live example here.

Hardware acceleration for smoother transitions

For smoother transitions hardware acceleration, which is achieved by using translate3d instead of the 2D translations, should be used whenever possible. For example, to realize a mobile app transition between pages one might use:

.page-enter,
.page-leave {
  position: absolute;
  -webkit-transition: transform 250ms ease-in-out, opacity 250ms ease-in-out;
  transition: transform 250ms ease-in-out, opacity 250ms ease-in-out;
}

.page-enter {
  left: 100vw;
}

.page-enter.page-enter-active {
  -webkit-transform: translate3d(-100vw, 0, 0);
  transform: translate3d(-100vw, 0, 0);
}

.page-leave {
  left: 0;
}

.page-leave.page-leave-active {
  -webkit-transform: translate3d(-100vw, 0, 0);
  transform: translate3d(-100vw, 0, 0);
}
<ReactCSSTransitionReplace
  transitionName="page"
  transitionEnterTimeout={250}
  transitionLeaveTimeout={250}
>
  <div key="page01">My page 01 content</div>
</ReactCSSTransitionReplace>

Tips

  1. In general animating block or inline-block level elements is more stable that inline elements. If the height changes in random ways ensure that there isn't a span or other inline element used as the outer element of the components being animated.
  2. The overflow of the container is set to 'hidden' automatically, which changes the behaviour of collapsing margins from the default 'visible'. This may cause a glitch in the height at the start or end of animations. To avoid this you can:
    • Keep the overflow hidden permanently with custom styles/classes if that will not cause undesired side-effects.
    • Only use Single-direction margin declarations to avoid collapsing margins overall.
    • Turn this feature off by setting the overflowHidden={false} prop when hidden overflow is not needed, for example when transitions are in place and content is of the same height.
  3. If the .*-height class (or transitionName.height) is not specified the change in container height will not be animated but instead jump to the height of the entering component instantaneously. It can, therefore, be omitted if all content is known to be of the same height without any adverse side-effects, and absolute positioning related height issues will still be avoided.

Contributing

PRs are welcome.

License

This software is free to use under the MIT license. See the LICENSE file for license text and copyright information.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].