Reputation: 199
I'v tried to use react-router and ReactTransitionGroup to make an navigation effect(page slide whereas route changes).
However, it's error-prone and ugly.(made much logic to define which direction to slide to and remove/add classes to make transition work).
I doubt is there any nice plugin to use.
Here's piece of my code, which inspired by Hardware-Accelerated Page Transitions for Mobile Web Apps / PhoneGap Apps.
const keyHistory = [];
let dir = 0;
const PageMixin = {
componentWillAppear(cb) {
keyHistory.push(this.props.location.key);
let $el = $(ReactDom.findDOMNode(this));
$el.addClass(pageStyles.right);
$el.one('transitionend', () => {
$el.removeClass(`${pageStyles.right} ${pageStyles.active}`);
cb();
});
requestAnimationFrame(() => {
$el.addClass(`${pageStyles.active} ${pageStyles.center}`);
});
},
componentWillEnter(cb) {
let key = this.props.location.key,
len = keyHistory.length;
if (key === keyHistory[len - 2]) {
keyHistory.pop();
dir = -1;
} else {
keyHistory.push(key);
dir = 1;
}
const fromDir = dir === -1 ? pageStyles.left : pageStyles.right;
let $el = $(ReactDom.findDOMNode(this));
$el.addClass(fromDir);
requestAnimationFrame(() => {
$el.removeClass(fromDir).addClass(`${pageStyles.active} ${pageStyles.center}`);
});
$el.one('transitionend', () => {
$el.removeClass(`${fromDir} ${pageStyles.active}`);
cb();
});
},
componentWillLeave(cb) {
const toDir = dir === -1 ? pageStyles.right : pageStyles.left;
let $el = $(ReactDom.findDOMNode(this));
requestAnimationFrame(() => {
$el.removeClass(pageStyles.center).addClass(`${pageStyles.active} ${toDir}`);
});
$el.one('transitionend', () => {
$el.removeClass(pageStyles.active);
cb();
});
}
};
Upvotes: 6
Views: 8583
Reputation: 2813
Coming in abit late but, without any other packages, There's a nice example in the examples of react-router right Here
Using ReactCSSTransitionGroup would look like this:
<ReactCSSTransitionGroup
component="div"
transitionName={ location.action !== 'POP' ? 'slide': 'slide-back' }
transitionEnterTimeout={1000}
transitionLeaveTimeout={1000}>
{React.cloneElement(children, { key: location.pathname })}
</ReactCSSTransitionGroup>
for the slide you can use the method shown in Sliding React Components:
.slide-enter {
transform: translate(100%);
}
.slide-enter.slide-enter-active {
transform: translate(0%);
transition: transform 1000ms ease-in-out;
}
.slide-leave {
transform: translate(0%);
}
.slide-leave.slide-leave-active {
transform: translate(-100%);
transition: transform 1000ms ease-in-out;
}
.slide-back-enter{
transform: translate(-100%);
}
.slide-back-enter.bg-back-enter-active {
transform: translate(0%);
transition: transform 1000ms ease-in-out;
}
.slide-back-leave {
transform: translate(0%);
}
.slide-back-leave.bg-back-leave-active {
transform: translate(0%);
transition: transform 1000ms ease-in-out;
}
Upvotes: 2
Reputation: 8681
You could be interested having a look at https://github.com/doctolib/react-router-transitions. This plugin handles the logic part of the transition.
You would still have to handle the actual transition on your side. E.g. by using ReactTransitionGroup
.
Upvotes: 2
Reputation: 145
You can try this
https://github.com/oliviertassinari/react-swipeable-views
Partial code from github
<SwipeableViews>
<div>
slide 1
</div>
<div>
slide 2
</div>
<div>
slide 3
</div>
</SwipeableViews>
Upvotes: 2