Вроде бы анимация смены контекста

This commit is contained in:
SleepWalker 2016-02-06 11:03:51 +02:00
parent 13d220087f
commit 57d30f1c79

View File

@ -10,14 +10,14 @@ import icons from 'components/ui/icons.scss';
const opacitySpringConfig = [200, 20]; const opacitySpringConfig = [200, 20];
const heightSpringConfig = [200, 18]; const transformSpringConfig = [500, 50];
const transformSpringConfig = [500, 20];
// TODO: сделать более быстрый фейд на горизонтальном скролле // TODO: сделать более быстрый фейд на горизонтальном скролле
export default class PanelTransition extends Component { export default class PanelTransition extends Component {
state = { state = {
height: {} height: {},
contextHeight: 0
}; };
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
@ -27,9 +27,10 @@ export default class PanelTransition extends Component {
var prev = previousRoute && previousRoute.pathname; var prev = previousRoute && previousRoute.pathname;
var direction = this.getDirection(next, next, prev); var direction = this.getDirection(next, next, prev);
var forceHeight = direction === 'Y' ? 1 : 0; var forceHeight = direction === 'Y' && next !== prev ? 1 : 0;
this.setState({ this.setState({
direction,
forceHeight: forceHeight, forceHeight: forceHeight,
previousRoute: this.props.location previousRoute: this.props.location
}); });
@ -42,9 +43,9 @@ export default class PanelTransition extends Component {
} }
render() { render() {
var {previousRoute, height} = this.state; var {previousRoute, height, contextHeight, forceHeight} = this.state;
var {path, Title, Body, Footer, Links} = this.props; const {path, Title, Body, Footer, Links} = this.props;
return ( return (
<TransitionMotion <TransitionMotion
@ -59,7 +60,8 @@ export default class PanelTransition extends Component {
opacitySpring: spring(1, opacitySpringConfig) opacitySpring: spring(1, opacitySpringConfig)
}, },
common: { common: {
heightSpring: spring(this.state.forceHeight || height[path] || 0, transformSpringConfig) heightSpring: spring(forceHeight || height[path] || 0, transformSpringConfig),
switchContextHeightSpring: spring(forceHeight || contextHeight, [500, 20])
} }
}} }}
willEnter={this.willEnter} willEnter={this.willEnter}
@ -79,6 +81,11 @@ export default class PanelTransition extends Component {
{keys.map((key) => this.getHeader(key, items[key]))} {keys.map((key) => this.getHeader(key, items[key]))}
</div> </div>
</PanelHeader> </PanelHeader>
<div style={{
overflow: 'hidden',
height: forceHeight ? items.common.switchContextHeightSpring : 'auto'
}}>
<ReactHeight onHeightReady={this.updateContextHeight}>
<PanelBody style={{ <PanelBody style={{
overflow: 'hidden' overflow: 'hidden'
}}> }}>
@ -98,6 +105,8 @@ export default class PanelTransition extends Component {
{keys.map((key) => this.getFooter(key, items[key]))} {keys.map((key) => this.getFooter(key, items[key]))}
</div> </div>
</PanelFooter> </PanelFooter>
</ReactHeight>
</div>
</Panel> </Panel>
<div className={helpLinksStyles} style={{position: 'relative', height: '20px'}}> <div className={helpLinksStyles} style={{position: 'relative', height: '20px'}}>
{keys.map((key) => this.getLinks(key, items[key]))} {keys.map((key) => this.getLinks(key, items[key]))}
@ -152,12 +161,32 @@ export default class PanelTransition extends Component {
}); });
}; };
updateContextHeight = (height) => {
this.setState({
contextHeight: height
});
};
onGoBack = (event) => { onGoBack = (event) => {
event.preventDefault(); event.preventDefault();
this.props.history.goBack(); this.props.history.goBack();
}; };
getDirection(key, next, prev) {
var not = (path) => prev !== path && next !== path;
var map = {
'/login': not('/password') ? 'Y' : 'X',
'/password': not('/login') ? 'Y' : 'X',
'/register': not('/activation') ? 'Y' : 'X',
'/activation': not('/register') ? 'Y' : 'X',
'/oauth/permissions': 'Y'
};
return map[key];
}
getHeader(key, props) { getHeader(key, props) {
var {hasBackButton, transformSpring, Title} = props; var {hasBackButton, transformSpring, Title} = props;
@ -198,21 +227,18 @@ export default class PanelTransition extends Component {
getBody(key, props) { getBody(key, props) {
var {transformSpring, opacitySpring, Body} = props; var {transformSpring, opacitySpring, Body} = props;
var {previousRoute} = this.state; var {direction} = this.state;
var next = this.props.path; var transform = {
var prev = previousRoute && previousRoute.pathname; WebkitTransform: `translate${direction}(${transformSpring}%)`,
transform: `translate${direction}(${transformSpring}%)`
};
var direction = this.getDirection(key, next, prev);
var verticalOrigin = 'top'; var verticalOrigin = 'top';
if (direction === 'Y') { // TODO: do not activate animation when nothing was unmounted if (direction === 'Y') {
transformSpring = Math.abs(transformSpring);
if (prev === key) {
transformSpring *= -1;
}
verticalOrigin = 'bottom'; verticalOrigin = 'bottom';
transform = {};
} }
var style = { var style = {
@ -220,9 +246,8 @@ export default class PanelTransition extends Component {
[verticalOrigin]: 0, [verticalOrigin]: 0,
left: 0, left: 0,
width: '100%', width: '100%',
WebkitTransform: `translate${direction}(${transformSpring}%)`, opacity: opacitySpring,
transform: `translate${direction}(${transformSpring}%)`, ...transform
opacity: opacitySpring
}; };
return ( return (
@ -232,20 +257,6 @@ export default class PanelTransition extends Component {
); );
} }
getDirection(key, next, prev) {
var not = (path) => prev !== path && next !== path;
var map = {
'/login': not('/password') ? 'Y' : 'X',
'/password': not('/login') ? 'Y' : 'X',
'/register': not('/activation') ? 'Y' : 'X',
'/activation': not('/register') ? 'Y' : 'X',
'/oauth/permissions': 'Y'
};
return map[key];
}
getFooter(key, props) { getFooter(key, props) {
var {opacitySpring, Footer} = props; var {opacitySpring, Footer} = props;