Merge pull request #3 from erickreutz/eric-interpolated-background
Animate headerBackground between scene transitions
This commit is contained in:
commit
6a76bf6703
|
@ -80,6 +80,7 @@ class Header extends React.PureComponent {
|
||||||
titleFromLeftInterpolator: HeaderStyleInterpolator.forCenterFromLeft,
|
titleFromLeftInterpolator: HeaderStyleInterpolator.forCenterFromLeft,
|
||||||
titleInterpolator: HeaderStyleInterpolator.forCenter,
|
titleInterpolator: HeaderStyleInterpolator.forCenter,
|
||||||
rightInterpolator: HeaderStyleInterpolator.forRight,
|
rightInterpolator: HeaderStyleInterpolator.forRight,
|
||||||
|
backgroundInterpolator: HeaderStyleInterpolator.forBackground,
|
||||||
};
|
};
|
||||||
|
|
||||||
static get HEIGHT() {
|
static get HEIGHT() {
|
||||||
|
@ -338,6 +339,29 @@ class Header extends React.PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_renderBackground(props) {
|
||||||
|
const {
|
||||||
|
index,
|
||||||
|
key,
|
||||||
|
descriptor: { options },
|
||||||
|
} = props.scene;
|
||||||
|
|
||||||
|
const offset = this.props.navigation.state.index - index;
|
||||||
|
|
||||||
|
if (Math.abs(offset) > 2) {
|
||||||
|
// Scene is far away from the active scene. Hides it to avoid unnecessary
|
||||||
|
// rendering.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._renderSubView(
|
||||||
|
{ ...props, style: StyleSheet.absoluteFill },
|
||||||
|
'background',
|
||||||
|
() => options.headerBackground,
|
||||||
|
this.props.backgroundInterpolator
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
_renderModularSubView(
|
_renderModularSubView(
|
||||||
props,
|
props,
|
||||||
name,
|
name,
|
||||||
|
@ -492,6 +516,7 @@ class Header extends React.PureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let appBar;
|
let appBar;
|
||||||
|
let background;
|
||||||
const { mode, scene, isLandscape } = this.props;
|
const { mode, scene, isLandscape } = this.props;
|
||||||
|
|
||||||
if (mode === 'float') {
|
if (mode === 'float') {
|
||||||
|
@ -505,12 +530,16 @@ class Header extends React.PureComponent {
|
||||||
scene,
|
scene,
|
||||||
}));
|
}));
|
||||||
appBar = scenesProps.map(this._renderHeader, this);
|
appBar = scenesProps.map(this._renderHeader, this);
|
||||||
|
background = scenesProps.map(this._renderBackground, this);
|
||||||
} else {
|
} else {
|
||||||
appBar = this._renderHeader({
|
const headerProps = {
|
||||||
position: new Animated.Value(this.props.scene.index),
|
position: new Animated.Value(this.props.scene.index),
|
||||||
progress: new Animated.Value(0),
|
progress: new Animated.Value(0),
|
||||||
scene: this.props.scene,
|
scene: this.props.scene,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
appBar = this._renderHeader(headerProps);
|
||||||
|
background = this._renderBackground(headerProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { options } = scene.descriptor;
|
const { options } = scene.descriptor;
|
||||||
|
@ -590,9 +619,7 @@ class Header extends React.PureComponent {
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<SafeAreaView forceInset={forceInset} style={containerStyles}>
|
<SafeAreaView forceInset={forceInset} style={containerStyles}>
|
||||||
<View style={StyleSheet.absoluteFill}>
|
{background}
|
||||||
{options.headerBackground}
|
|
||||||
</View>
|
|
||||||
<View style={styles.flexOne}>{appBar}</View>
|
<View style={styles.flexOne}>{appBar}</View>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
|
|
|
@ -325,6 +325,27 @@ function forCenterFromLeft(props) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BACKGROUND_OFFSET = Dimensions.get('window').width;
|
||||||
|
function forBackground(props) {
|
||||||
|
const { position, scene, scenes } = props;
|
||||||
|
const interpolate = getSceneIndicesForInterpolationInputRange(props);
|
||||||
|
if (!interpolate) return { opacity: 0 };
|
||||||
|
const { first, last } = interpolate;
|
||||||
|
const index = scene.index;
|
||||||
|
const offset = BACKGROUND_OFFSET;
|
||||||
|
const outputRange = [offset, 0, -offset];
|
||||||
|
return {
|
||||||
|
transform: [
|
||||||
|
{
|
||||||
|
translateX: position.interpolate({
|
||||||
|
inputRange: [first, index, last],
|
||||||
|
outputRange: I18nManager.isRTL ? outputRange.reverse() : outputRange,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
forLayout,
|
forLayout,
|
||||||
forLeft,
|
forLeft,
|
||||||
|
@ -333,4 +354,5 @@ export default {
|
||||||
forCenterFromLeft,
|
forCenterFromLeft,
|
||||||
forCenter,
|
forCenter,
|
||||||
forRight,
|
forRight,
|
||||||
|
forBackground,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue