Reputation: 2748
I am trying to create a basic animation with React Motion: I have two elements, either of which can be displayed depending on the component state. When the state changes, I want one element to replace the other. The replacement animation is a combination of sliding to the left and fading out of the leaving element.
Problem: When the state is changed, the leaving element becomes indistinguishable from the entering element.
Illustration: Here, in the codepen where I reproduced the problem, clicking on a colored shape will change the component's state and will replace the element. Notice that the leaving component becomes the same as the component that enters (e.g. when a circle is clicked, it changes to the square and leaves). I would expect the leaving element to remain its initial shape.
Here is the copy of the code of the component from CodePen:
const spring = ReactMotion.spring;
const TransitionMotion = ReactMotion.TransitionMotion;
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
mode: 'foo'
}
}
changeMode() {
const { mode: currentMode } = this.state;
this.setState({
mode: currentMode === 'foo' ? 'bar' : 'foo'
});
}
willEnter() {
return { opacity: 0, translateX: 200 };
}
willLeave() {
return { opacity: spring(0), translateX: spring(-200, { stiffness: 140, damping: 20 }) };
}
render() {
const { mode } = this.state;
const styles = [mode].map(mode => {
return {
key: mode,
style: {
opacity: spring(1),
translateX: spring(0, { stiffness: 140, damping: 12 })
}
}
});
return (
<div className="container">
<TransitionMotion
styles={styles}
willEnter={this.willEnter}
willLeave={this.willLeave}
>
{ interpolatedStyles =>
<div style={{ position: 'relative' }}>
{
interpolatedStyles.map(config => {
return mode === 'foo' ? this.renderFoo(config) : this.renderBar(config);
})
}
</div>
}
</TransitionMotion>
<div className="label"> Click the shape </div>
</div>
);
}
renderFoo(config) {
console.log('config', config);
return (
<div
key={config.key}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '150px',
height: '150px',
borderRadius: '100%',
backgroundColor: 'red',
opacity: config.style.opacity,
transform: `translateX(${config.style.translateX}%)`
}}
onClick={ () => this.changeMode() }
/>
);
}
renderBar(config) {
return (
<div
key={config.key}
style={{
...config.styles,
position: 'absolute',
top: 0,
left: 0,
width: '150px',
height: '150px',
backgroundColor: 'blue',
opacity: config.style.opacity,
transform: `translateX(${config.style.translateX}%)`
}}
onClick={ () => this.changeMode() }
/>
);
}
}
Could you please suggest how to fix the animation so that the leaving element was visually the correct one?
Upvotes: 0
Views: 181