我尝试创建一个能够在两个图像之间创建淡入淡出的<Background>
组件。在第一次渲染时,图像应从透明变为完全不透明;在后续渲染中,应保留上一张图像并将其用作淡入淡出的起点,这样您就可以看到新图像在前一张图像的顶部淡入。
所以我的逻辑是:
componentWillReceiveProps
上我将当前道具保存到this.state.previousBackground
之前丢失; 0
设置为1
。它做了它应该做的事情,但图像在每次转换时都会闪烁。就像我可以看到新背景的完全不透明度瞬间消失并开始逐渐消失。
如果有人知道可能导致这种情况的原因,我们将非常感激。我附上了我的组件的代码,如果有任何问题不清楚,请告诉我。
我使用RN 0.21。
非常感谢!
编辑:我还尝试过不使用position: absolute
,但保持之前的背景相对定位,并使用translateY
将新背景移到其上面。结果是一样的。
'use strict';
// --------------------------------------------------------------
// React components
// --------------------------------------------------------------
var React = require('react-native');
var {
Animated,
Dimensions,
Image,
StyleSheet,
View
} = React;
// --------------------------------------------------------------
// Application components
// --------------------------------------------------------------
var Animations = require('./Animations');
var BaseStyle = require('../utils/BaseStyle');
var Constants = require('../constants/AppConstants');
var EpisodeActions = require('../actions/EpisodeActions');
var Video = require('react-native-video').default;
// --------------------------------------------------------------
// Component declaration
// --------------------------------------------------------------
var Background = React.createClass({
_animate: function () {
Animated.timing(this.state.opacity, {
toValue: this.props.opacity,
duration: fadeDuration
}).start(EpisodeActions.backgroundFinishedAnimating);
},
_renderBackground: function (background, isPreviousBackground) {
if (!background) {
return null;
}
var imageStyle = {};
if (!isPreviousBackground) {
imageStyle.opacity = this.state.opacity;
}
return (
<Animated.Image
//resizeMode="cover"
source={{uri: background.src}}
style={[styles.fullScreen, imageStyle]}
/>
);
},
getDefaultProps: function () {
return {
backdropColor: '#000',
opacity: 1
};
},
getInitialState: function () {
return {
opacity: new Animated.Value(0),
previousBackground: null
};
},
componentDidMount: function () {
//this._animate();
},
componentWillReceiveProps: function (newProps) {
var newState = {
opacity: new Animated.Value(0)
};
if (newProps.data.src !== this.props.data.src) {
newState.previousBackground = this.props.data;
}
this.setState(newState);
},
shouldComponentUpdate: function (newProps, newState) {
if (this.props.data.src === newProps.data.src) {
return false;
}
return true;
},
componentDidUpdate: function (oldProps, oldState) {
//this._animate();
},
render: function () {
this._animate();
return (
<View style={[styles.fullScreen, {backgroundColor: this.props.backdropColor}]}>
{this._renderBackground(this.state.previousBackground, true)}
{this._renderBackground(this.props.data)}
</View>
);
}
});
// --------------------------------------------------------------
// Styling
// --------------------------------------------------------------
var styles = StyleSheet.create({
fullScreen: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
});
module.exports = Background;