在React Native中在两个图像之间创建淡入淡出时图像闪烁

时间:2016-03-09 17:25:44

标签: reactjs react-native

我尝试创建一个能够在两个图像之间创建淡入淡出的<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;

0 个答案:

没有答案