Skip to content

Instantly share code, notes, and snippets.

@kasper573
Created February 24, 2018 17:49
Show Gist options
  • Save kasper573/41a1909a84e144fc66aa29fbd8bee1b7 to your computer and use it in GitHub Desktop.
Save kasper573/41a1909a84e144fc66aa29fbd8bee1b7 to your computer and use it in GitHub Desktop.
import * as React from 'react';
import {IObservableValue} from 'mobx';
import {observer} from 'mobx-react';
import Transition from 'react-transition-group/Transition';
import {WithTheme} from 'material-ui';
import withTheme from 'material-ui/styles/withTheme';
export type TransitionVector = {
x: number,
y: number,
z: number
};
export type TransitionState = 'entering' | 'entered';
export type AxisTransitionProps = Partial<WithTheme> & {
in?: boolean,
direction: IObservableValue<TransitionVector>,
movement: TransitionVector
};
@(withTheme as any)()
@observer
export class AxisTransition extends React.Component<AxisTransitionProps> {
get visibleStyle () {
return {opacity: 1, transform: `translate3d(0, 0, 0)`};
}
createTranslateOrigin (state: TransitionState) {
const {x, y, z} = this.props.direction.get();
const m1 = this.props.in ? -1 : 1;
const m2 = this.isEnterState(state) ? -1 : 1;
return {
x: x * this.props.movement.x * m1 * m2,
y: y * this.props.movement.y * m1 * m2,
z: z * this.props.movement.z * m1 * m2
};
}
createHiddenStyle (state: TransitionState) {
const {x, y, z} = this.createTranslateOrigin(state);
return {opacity: 0, transform: `translate3d(${x}px, ${y}px, ${z}px)`};
}
createStyle (state: TransitionState) {
const {theme} = this.props;
const transitionStyle = this.isEnterState(state) ?
this.visibleStyle :
this.createHiddenStyle(state);
return {
...transitionStyle,
transition: theme.transitions.create(
['opacity', 'transform'],
{duration: theme.transitions.duration.enteringScreen}
)
};
}
isEnterState (state: TransitionState) {
return state === 'entered' || state === 'entering';
}
addEndListener = (node: HTMLElement, done: () => void) => {
node.addEventListener('transitionend', done, false);
}
render () {
const {children, theme, direction, movement, ...rest} = this.props;
return (
<Transition timeout={null} appear onEnter={reflow} addEndListener={this.addEndListener} {...rest}>
{(state: TransitionState, childProps: any) => (
React.cloneElement(children as any, {
style: this.createStyle(state),
...childProps
})
)}
</Transition>
);
}
}
function reflow (node: HTMLElement) {
node.scrollTop;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment