Повысил fps анимаций переходов

This commit is contained in:
SleepWalker 2016-03-27 10:52:00 +03:00
parent 7ab387fb71
commit a17c70fcc1
4 changed files with 59 additions and 17 deletions

View File

@ -20,7 +20,6 @@
"intl-messageformat": "^1.1.0", "intl-messageformat": "^1.1.0",
"react": "^15.0.0-rc.2", "react": "^15.0.0-rc.2",
"react-dom": "^15.0.0-rc.2", "react-dom": "^15.0.0-rc.2",
"react-height": "^2.0.3",
"react-helmet": "^2.3.1", "react-helmet": "^2.3.1",
"react-intl": "=v2.0.0-rc-1", "react-intl": "=v2.0.0-rc-1",
"react-motion": "^0.4.0", "react-motion": "^0.4.0",

View File

@ -0,0 +1,34 @@
import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
export default class MeasureHeight extends Component {
static propTypes = {
shouldMeasure: PropTypes.func,
onMeasure: PropTypes.func
};
static defaultProps = {
shouldMeasure: (prevState, newState) => prevState !== newState,
onMeasure: () => null
};
componentDidMount() {
this.el = ReactDOM.findDOMNode(this);
this.measure();
}
componentDidUpdate(prevProps) {
if (this.props.shouldMeasure(prevProps.state, this.props.state)) {
this.measure();
}
}
render() {
return <div {...this.props} />;
}
measure() {
this.props.onMeasure(this.el.offsetHeight);
}
}

View File

@ -2,7 +2,6 @@ import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { TransitionMotion, spring } from 'react-motion'; import { TransitionMotion, spring } from 'react-motion';
import ReactHeight from 'react-height';
import { Panel, PanelBody, PanelFooter, PanelHeader } from 'components/ui/Panel'; import { Panel, PanelBody, PanelFooter, PanelHeader } from 'components/ui/Panel';
import { Form } from 'components/ui/Form'; import { Form } from 'components/ui/Form';
@ -13,6 +12,7 @@ import authFlow from 'services/authFlow';
import { userShape } from 'components/user/User'; import { userShape } from 'components/user/User';
import * as actions from './actions'; import * as actions from './actions';
import MeasureHeight from './MeasureHeight';
const opacitySpringConfig = {stiffness: 300, damping: 20}; const opacitySpringConfig = {stiffness: 300, damping: 20};
const transformSpringConfig = {stiffness: 500, damping: 50}; const transformSpringConfig = {stiffness: 500, damping: 50};
@ -70,7 +70,6 @@ class PanelTransition extends Component {
} }
state = { state = {
height: {},
contextHeight: 0 contextHeight: 0
}; };
@ -98,10 +97,12 @@ class PanelTransition extends Component {
} }
render() { render() {
const {height, canAnimateHeight, contextHeight, forceHeight} = this.state; const {canAnimateHeight, contextHeight, forceHeight} = this.state;
const {path, Title, Body, Footer, Links} = this.props; const {path, Title, Body, Footer, Links} = this.props;
const formHeight = this.state[`formHeight${path}`] || 0;
if (this.props.children) { if (this.props.children) {
return this.props.children; return this.props.children;
} else if (!Title || !Body || !Footer || !Links) { } else if (!Title || !Body || !Footer || !Links) {
@ -116,7 +117,7 @@ class PanelTransition extends Component {
opacitySpring: spring(1, opacitySpringConfig) opacitySpring: spring(1, opacitySpringConfig)
}}, }},
{key: 'common', style: { {key: 'common', style: {
heightSpring: spring(forceHeight || height[path] || 0, transformSpringConfig), heightSpring: spring(forceHeight || formHeight, transformSpringConfig),
switchContextHeightSpring: spring(forceHeight || contextHeight, changeContextSpringConfig) switchContextHeightSpring: spring(forceHeight || contextHeight, changeContextSpringConfig)
}} }}
]} ]}
@ -134,7 +135,7 @@ class PanelTransition extends Component {
const bodyHeight = { const bodyHeight = {
position: 'relative', position: 'relative',
height: `${canAnimateHeight ? common.style.heightSpring : height[path]}px` height: `${canAnimateHeight ? common.style.heightSpring : formHeight}px`
}; };
return ( return (
@ -144,7 +145,10 @@ class PanelTransition extends Component {
{panels.map((config) => this.getHeader(config))} {panels.map((config) => this.getHeader(config))}
</PanelHeader> </PanelHeader>
<div style={contentHeight}> <div style={contentHeight}>
<ReactHeight onHeightReady={this.onUpdateContextHeight}> <MeasureHeight
state={this.props.auth.error}
onMeasure={this.onUpdateContextHeight}
>
<PanelBody> <PanelBody>
<div style={bodyHeight}> <div style={bodyHeight}>
{panels.map((config) => this.getBody(config))} {panels.map((config) => this.getBody(config))}
@ -153,7 +157,7 @@ class PanelTransition extends Component {
<PanelFooter> <PanelFooter>
{panels.map((config) => this.getFooter(config))} {panels.map((config) => this.getFooter(config))}
</PanelFooter> </PanelFooter>
</ReactHeight> </MeasureHeight>
</div> </div>
</Panel> </Panel>
<div className={helpLinksStyles}> <div className={helpLinksStyles}>
@ -223,15 +227,16 @@ class PanelTransition extends Component {
return map[next]; return map[next];
} }
onUpdateHeight = (height) => { onUpdateHeight = (height, key) => {
const canAnimateHeight = Object.keys(this.state.height).length > 1 || this.state.height[[this.props.path]]; const heightKey = `formHeight${key}`;
// we need to skip first render, because there is no panel to make transition from
// const canAnimateHeight = Object.keys(this.state.height).length > 1 || this.state[heightKey];
const canAnimateHeight = true;
this.setState({ this.setState({
canAnimateHeight, canAnimateHeight,
height: { [heightKey]: height
...this.state.height,
[this.props.path]: height
}
}); });
}; };
@ -300,13 +305,18 @@ class PanelTransition extends Component {
}; };
return ( return (
<ReactHeight key={`body${key}`} style={style} onHeightReady={this.onUpdateHeight}> <MeasureHeight
key={`body${key}`}
style={style}
state={this.props.auth.error}
onMeasure={(height) => this.onUpdateHeight(height, key)}
>
{React.cloneElement(Body, { {React.cloneElement(Body, {
ref: (body) => { ref: (body) => {
this.body = body; this.body = body;
} }
})} })}
</ReactHeight> </MeasureHeight>
); );
} }

View File

@ -53,7 +53,6 @@ var webpackConfig = {
'intl-messageformat', 'intl-messageformat',
'react', 'react',
'react-dom', 'react-dom',
'react-height',
'react-helmet', 'react-helmet',
'react-intl', 'react-intl',
'react-motion', 'react-motion',