I tried to implement fade in/fade out animation in React using ReactCSSTransitionGroup. I followed this solution in of previous SO answers. I have a component which contains an image and text. Animation is smooth for text, but not for the image. It looks like image flickers during animation.
js
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var items = [
{id: 1, text: "item1", img: "https://mirrors.creativecommons.org/presskit/icons/cc.large.png"},
{id: 2, text: "item2", img: "https://mirrors.creativecommons.org/presskit/icons/by.large.png"},
{id: 3, text: "item3", img: "https://mirrors.creativecommons.org/presskit/icons/nc.large.png"},
{id: 4, text: "item4", img: "https://mirrors.creativecommons.org/presskit/icons/nc-eu.large.png"},
]
function findObjectByKey(array, key, value) {
for (var i = 0; i < array.length; i++) {
if (array[i][key] === value) {
return array[i];
}
}
return null;
}
var SwitchContent = React.createClass({
render: function() {
var obj = findObjectByKey(items, 'id', this.props.id);
console.log(obj);
return (
<div>
<style
dangerouslySetInnerHTML={{
__html: [
'.backgroundImg {',
' background: url('+obj.img+');',
' background-size: auto 100px;',
'}',
].join('\n'),
}}
/>
<div className="backgroundImg" />
<div className="textContent">{obj.text}</div>
</div>
);
}
});
var Switch = React.createClass({
getInitialState: function() {
return {
id: 1,
};
},
toggle: function(e) {
this.setState({ id: this.state.id === 4 ? 1 : this.state.id + 1 });
},
render: function() {
var key = this.state.id;
return (
<div>
<button onClick={this.toggle}>Toggle</button>
<ReactCSSTransitionGroup
transitionAppear
transitionAppearTimeout={500}
transitionLeaveTimeout={500}
transitionEnterTimeout={500}
className="container"
transitionName="example">
<div key={key} className="item_container">
<SwitchContent id={key} />
</div>
</ReactCSSTransitionGroup>
</div>
);
}
});
React.render(<Switch/>, document.getElementById("switch"));
CSS
.backgroundImg {
background-repeat: no-repeat;
background-position: center center;
background-color: black;
width: 100px;
height: 100px;
}
.container {
position: relative;
}
.container > div {
position: absolute;
}
.button {
display: block;
height: 100px;
width: 100px;
border: 1px solid #aaa;
border-radius: 25px;
font: bold 20px Helvetica, Arial, sans-serif;
text-align: center;
line-height: 100px;
cursor: pointer;
color: #fff;
background-color: #000;
/* Define transition on the "opacity" property. */
transition: opacity 0.5s ease-in;
}
.example-enter {
opacity: 0.01;
}
.example-enter.example-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
.example-leave {
opacity: 1;
}
.example-leave.example-leave-active {
opacity: 0.01;
transition: opacity 500ms ease-in;
}