Skip to content

Instantly share code, notes, and snippets.

@dedan
Created November 24, 2016 10:40
Show Gist options
  • Save dedan/c68db3aa798ba96e285bdd11fafb9556 to your computer and use it in GitHub Desktop.
Save dedan/c68db3aa798ba96e285bdd11fafb9556 to your computer and use it in GitHub Desktop.
FadeInFadeOut
require('normalize.css/normalize.css');
require('styles/App.css');
import React from 'react';
const ObjectOne = () => {
return <div style={{width: 100, height: 100, backgroundColor: 'red'}} />
}
const ObjectTwo = () => {
return <div style={{width: 100, height: 100, backgroundColor: 'green'}} />
}
class FadeInFadeOut extends React.Component {
static propTypes = {
children: React.PropTypes.element,
transitionDurationMillisec: React.PropTypes.number,
}
static defaultProps = {
transitionDurationMillisec: 800,
}
constructor(props) {
super(props)
this.state = {
isFadingIn: false,
isFadingOut: false,
isInTransition: false,
nodeShown: props.children,
}
// The state will be modified like this during a transition:
// isFadingIn isFadingOut nodeShown
// false false 1
// false true 1
// ...
// true false 2
// false false 2
// ...
// end
}
componentWillReceiveProps(nextProps) {
if (nextProps.children.key === this.props.children.key) {
return
}
if (this.timeout) {
clearTimeout(this.timeout)
}
this.setState({
isInTransition: true,
nextNode: nextProps.children,
}, this.startFadingOut)
}
startFadingOut = () => {
this.setState({isFadingOut: true})
this.timeout = setTimeout(this.startFadingIn, this.props.transitionDurationMillisec / 2)
}
startFadingIn = () => {
this.setState({
isFadingIn: true,
isFadingOut: false,
nodeShown: this.state.nextNode,
}, this.endFadingIn)
}
endFadingIn = () => {
this.setState({
isFadingIn: false,
nextNode: null,
})
this.timeout = setTimeout(this.endTransition, this.props.transitionDurationMillisec / 2)
}
endTransition = () => {
this.setState({isInTransition: false})
}
componentWillUnmount() {
if (this.timeout) {
clearTimeout(this.timeout)
}
}
render() {
const {isFadingIn, isFadingOut, nodeShown} = this.state
const scale = isFadingOut || isFadingIn ? 0 : 1
const style = {
opacity: isFadingOut || isFadingIn ? 0 : 1,
transform: `scale(${scale}, ${scale})`,
transformOrigin: '50px 50px',
transition: `ease-in ${this.props.transitionDurationMillisec / 2}ms`,
}
return <div style={style}>
{nodeShown}
</div>
}
}
class AppComponent extends React.Component {
state = {
isFirstShown: true,
}
componentDidMount = () => {
setTimeout(() => this.setState({isFirstShown: false}), 2000)
}
render() {
const {isFirstShown} = this.state
return (
<div className="index">
<FadeInFadeOut>
{isFirstShown ? <ObjectOne key='thing1' /> : <ObjectTwo key='thing2' />}
</FadeInFadeOut>
</div>
);
}
}
AppComponent.defaultProps = {
};
export default AppComponent;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment