React Transition group not firing - reactjs

i tried to create a simple transition with react transition group, but i can't get it to work- transitions aren't working.
i did used a unique key.
for the example i just did a simple 2 image fade in fade out component:
var ReactCSSTransitionGroup = React.addons.TransitionGroup;
var Image = React.createClass({
getInitialState: function () {
return ({imglink: 'http://belaumi.com/wp-content/uploads/2014/11/3D-Animated-Frog-Image.jpg', status: 1})
},
update: function () {
console.log(this);
if (this.state.status==1)
{
this.setState({ imglink: 'http://www.codefuture.co.uk/projects/imagehost/demo/di/KXY1/Image-b%C3%A9b%C3%A9-facebook-8.jpg', status:2})
} else {
this.setState({ imglink: 'http://belaumi.com/wp-content/uploads/2014/11/3D-Animated-Frog-Image.jpg', status:1})
}
} ,
render: function () {
return (
<div>
<div className='container'>
<button onClick={this.update.bind(this)}>Click</button>
<ReactCSSTransitionGroup transitionName="example">
<img key={this.state.status} src={this.state.imglink}/>
</ReactCSSTransitionGroup>
</div>
</div>
);
}
});
React.render(
<div>
<Image/>
</div>,
document.getElementById('reactbody')
)
</script>
i've also included proper css:
.example-enter {
opacity: 0.01;
transition: opacity .5s ease-in;
-webkit-transition: opacity .5s ease-in;
}
.example-enter.example-enter-active {
opacity: 1;
}
.example-leave {
opacity: 1;
transition: opacity .5s ease-in;
-webkit-transition: opacity .5s ease-in;
}
.example-leave.example-leave-active {
opacity: 0.01;
}
any idea why this is not working? the image does switch, but no fade..
thanks!

The addons name is CSSTransitionGroup:
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
instead of
var ReactCSSTransitionGroup = React.addons.TransitionGroup;
(Notice the CSSTransitionGroup)
Working jsfiddle: http://jsfiddle.net/wvt30ocx/

Related

simple css animation not working on dynamic reactjs element

Check the snippet at codepen http://codepen.io/anon/pen/EZJjNO
Click on Add button, it will add another item but its appearing immediately without any fade effect.
JS:
class App extends React.Component {
constructor(props) {
super(props);
this.addItem = this.addItem.bind(this);
this.state = {
items: [1,2,3]
}
}
addItem() {
var items = this.state.items;
items.push(4);
this.setState({
items: items
})
}
render() {
return (
<div className="App">
{
this.state.items.map(function(i) {
return <div className="item fade">Testing</div>
})
}
<button onClick={this.addItem}>Add</button>
</div>
);
}
}
React.render(<App />, document.body);
CSS:
.App {
background-color: rgba(0,0,0, 0.5);
text-align: center;
height: 100vh;
}
div.item {
border: 1px solid #ccc;
padding: 10px;
background: #123456;
color: #fff;
opacity: 0;
transition: all 0.4s ease-out;
}
.fade {
opacity: 1 !important;
}
Since the fade class is added by default, you don't get the transition effect. If you open your browser's developer tools and remove the class, you'll see it fade away nicely.
There's a few ways to get what you want, but I'd just use a keyframe CSS animation like so:
.fade {
animation: 0.4s ease-out fadeIn 1;
}
#keyframes fadeIn {
0% {
opacity: 0;
visibility: hidden;
}
100% {
opacity: 1;
visibility: visible;
}
}
Here's a fork of your code pen showing how it works :)

React styled-components fade in/fade out

I am trying to build a React component to handle fading in and fading out. In the following code, if I pass out as a prop to the component, it is disaplayed as hidden before animating out. I'm trying to have it fade in by default, then fade out when I pass in the out prop. Anyone see a solution to this problem?
import React from 'react';
import styled, { keyframes } from 'styled-components';
const fadeIn = keyframes`
from {
transform: scale(.25);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
`;
const fadeOut = keyframes`
from {
transform: scale(1);
opacity: 0;
}
to {
transform: scale(.25);
opacity: 1;
}
`;
const Fade = styled.div`
${props => props.out ?
`display: none;`
: `display: inline-block;`
}
animation: ${props => props.out ? fadeOut : fadeIn} 1s linear infinite;
`;
function App() {
return (
<div>
<Fade><💅test></Fade>
</div>
);
}
export default App;
WebpackBin running example
The issue with your code is that you're setting the display property to none when props.out is true. That's why you're not seeing any animation, because before that can even start you've already hidden the component!
The way to do a fade out animation is to use the visibility property instead and transition that for the same amount of time as the animation takes. (see this old SO answer)
Something like this should solve your issues:
const Fade = styled.default.div`
display: inline-block;
visibility: ${props => props.out ? 'hidden' : 'visible'};
animation: ${props => props.out ? fadeOut : fadeIn} 1s linear;
transition: visibility 1s linear;
`;
const fadeIn = styled.keyframes`
from {
transform: scale(.25);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
`;
const fadeOut = styled.keyframes`
from {
transform: scale(1);
opacity: 1;
}
to {
transform: scale(.25);
opacity: 0;
}
`;
const Fade = styled.default.div`
display: inline-block;
visibility: ${props => props.out ? 'hidden' : 'visible'};
animation: ${props => props.out ? fadeOut : fadeIn} 1s linear;
transition: visibility 1s linear;
`;
class App extends React.Component {
constructor() {
super()
this.state = {
visible: true,
}
}
componentDidMount() {
setTimeout(() => {
this.setState({
visible: false,
})
}, 1000)
}
render() {
return (
<div>
<Fade out={!this.state.visible}><💅test></Fade>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>
<div id="root" />
Note: Your fadeOut animation also went from 0 to 1 opacity, instead of the other way around. I've fixed that in the snippet too.

exit animation will only work if start animation is in progress

I have this problem where the animation will only exit if the start animation is still in progress. Once the start animation finishes and I click another link it still adds the reverse class but only show a white page and the animation will not exit.
Here is the smoothstate call:
$(function(){
'use-strict';
var options = {
anchors: 'a',
prefetch: true,
blacklist: '.no-smoothState',
debug: true,
cacheLength: 2,
onStart: {
duration: 1000,
render: function($container) {
$container.addClass('is-exiting');
smoothState.restartCSSAnimations();
}
},
onReady: {
duration: 1000,
render: function($container, $newContent) {
$container.removeClass('is-exiting');
$container.html($newContent);
}
},
onAfter: function($container, $newContent) {
}
},
smoothState = $('#wrapper').smoothState(options).data('smoothState');
});
The HTML:
<div id="wrapper">
<div id="portfolio" class="portfolio">
<header>...</header>
<main id="content">
<section>
<h2>...</h2>
</section>
</main>
</div>
</div><!-- // wrapper -->
The CSS:
#wrapper #content {
animation-duration: 1s;
transition-timing-function: ease;
animation-fill-mode: forwards;
}
#wrapper #content {
animation-name: fadeInUp;
}
#wrapper.is-exiting #content {
animation-direction: alternate-reverse;
}
#keyframes fadeInUp {
0% {
opacity: 0;
transform: translateY(60px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
Got it to work. If you use classes instead of ID's when targeting the animation it will start the exit animation.

React CSS Transitions

I'm learning React CSS Transitions. So I decided to make a sliding sidebar navigation. The sidebar slides in from right just fine. But I can't get leave animations working. I'm not sure what's going on.
The jsx:
render: function() {
return(
<div className="_Sidebar">
<div className="top">
<i
className="menuIcon fa fa-bars"
onClick={() => this.handleClick()}>
</i>
<UserName />
</div>
{this.state.show ?
<ReactCSSTransitionGroup
transitionName="example"
transitionAppear={true}
transitionLeave={true} >
<div key={"slidebar"} className="sidebar">
{this.handleItems()}
</div>
</ReactCSSTransitionGroup>
: null}
</div>
);
}
And the css:
.example-appear {
left: -230px;
transition: left .9s ease-in;
}
.example-appear.example-appear-active {
left: 0px;
}
.example-leave {
left: 0px;
transition: left .9s ease-out;
}
.example-leave.example-leave-active {
left: -230px;
}
really I tried in your code there is a thing not right in putting ReactCSSTransitionGroup tag, so I attached my code , its woke correct, you can use it directly and put your data,
import React from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
var Test = React.createClass({
getInitialState: function () {
return { active: true };
},
onToggle: function () {
this.setState({active: !this.state.active});
},
render: function() {
return (
<div>
<ReactCSSTransitionGroup
transitionName="fade"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}>
{!this.state.active && ( <h2> Test Asmaa Almadhoun </h2>)}
</ReactCSSTransitionGroup>
<div className="chatBTN" onClick={this.onToggle}>
<img src="../src/contents/images/svg/chat.svg"/>
</div>
</div>
);
}
});
export default Test;
CSS File
.chatBar{
position: fixed;
height: 320px;
z-index: 0;
right: 0;
top: 40px;
width: 150px;
text-align: center;
display: block;
transform: translateY(-40px);
}
.fade-enter {
transform: translateY(-88%);
}
.fade-enter-active {
top: 0;
transform:translateY(-40px);
transition: .5s ease-in all;
}
.fade-leave {
transform: translateY(-40px);
}
.fade-leave-active {
transform: translateY(-88%);
transition: 0.3s ease-out all;
}

How to add page transitions to React without using the router?

I tried to add page transitions to my app using ReactCSSTransitionGroup but it did not work. For some pages it worked but for some it did not. Many examples out there show how to do it with the React router. But since I use Meteor, I use a different router (FlowRouter).
Here's my render method :
render() {
return (
<div>
{this.props.content()}
</div>
);
}
Here's how I tried to add transitions :
<ReactCSSTransitionGroup
transitionName="pageTransition"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}
transitionAppear={true}
transitionAppearTimeout={500}
>
{/* Content */}
{React.cloneElement(this.props.content(), {
key: uuid.v1(),
})}
</ReactCSSTransitionGroup>
The css :
//Page transition
.pageTransition-enter {
opacity: 0.01;
}
.pageTransition-enter.pageTransition-enter-active {
animation: fadeIn 1s ease-in;
}
.animation-leave {
opacity: 1;
}
.pageTransition-leave.pageTransition-leave-active {
animation: fadeIn 3s ease-in;
}
.pageTransition-appear {
opacity: 0.01;
}
.pageTransition-appear.pageTransition-appear-active {
animation: opacity 5s ease-in;
}
Any idea how to make this work?
I figured it out! Your CSS animations are trying to use fadeIn, but that's not a CSS property. You need to change it to opacity. Like so:
//Page transition
.pageTransition-enter {
opacity: 0.01;
}
.pageTransition-enter.pageTransition-enter-active {
animation: opacity 1s ease-in;
}
.animation-leave {
opacity: 1;
}
.pageTransition-leave.pageTransition-leave-active {
animation: opacity 3s ease-in;
}
.pageTransition-appear {
opacity: 0.01;
}
.pageTransition-appear.pageTransition-appear-active {
animation: opacity 5s ease-in;
}
try defining your inner component before return call:
render() {
const clonedElement = <div>{this.props.content()}</div>;
return (
<ReactCSSTransitionGroup transitionName="pageTransition" transitionEnterTimeout={500} transitionLeaveTimeout={300} transitionAppear={true} transitionAppearTimeout={500}>
{clonedElement}
</ReactCSSTransitionGroup>
);
}

Resources