CardStackStyleInterpolator.js 4.87 KB
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _reactNative = require('react-native');

var _getSceneIndicesForInterpolationInputRange = require('../../utils/getSceneIndicesForInterpolationInputRange');

var _getSceneIndicesForInterpolationInputRange2 = _interopRequireDefault(_getSceneIndicesForInterpolationInputRange);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Utility that builds the style for the card in the cards stack.
 *
 *     +------------+
 *   +-+            |
 * +-+ |            |
 * | | |            |
 * | | |  Focused   |
 * | | |   Card     |
 * | | |            |
 * +-+ |            |
 *   +-+            |
 *     +------------+
 */

/**
 * Render the initial style when the initial layout isn't measured yet.
 */
function forInitial(props) {
  var navigation = props.navigation,
      scene = props.scene;


  var focused = navigation.state.index === scene.index;
  var opacity = focused ? 1 : 0;
  // If not focused, move the scene far away.
  var translate = focused ? 0 : 1000000;
  return {
    opacity: opacity,
    transform: [{ translateX: translate }, { translateY: translate }]
  };
}

/**
 * Standard iOS-style slide in from the right.
 */
function forHorizontal(props) {
  var layout = props.layout,
      position = props.position,
      scene = props.scene;


  if (!layout.isMeasured) {
    return forInitial(props);
  }
  var interpolate = (0, _getSceneIndicesForInterpolationInputRange2.default)(props);

  if (!interpolate) return { opacity: 0 };

  var first = interpolate.first,
      last = interpolate.last;

  var index = scene.index;
  var opacity = position.interpolate({
    inputRange: [first, first + 0.01, index, last - 0.01, last],
    outputRange: [0, 1, 1, 0.85, 0]
  });

  var width = layout.initWidth;
  var translateX = position.interpolate({
    inputRange: [first, index, last],
    outputRange: _reactNative.I18nManager.isRTL ? [-width, 0, width * 0.3] : [width, 0, width * -0.3]
  });
  var translateY = 0;

  return {
    opacity: opacity,
    transform: [{ translateX: translateX }, { translateY: translateY }]
  };
}

/**
 * Standard iOS-style slide in from the bottom (used for modals).
 */
function forVertical(props) {
  var layout = props.layout,
      position = props.position,
      scene = props.scene;


  if (!layout.isMeasured) {
    return forInitial(props);
  }
  var interpolate = (0, _getSceneIndicesForInterpolationInputRange2.default)(props);

  if (!interpolate) return { opacity: 0 };

  var first = interpolate.first,
      last = interpolate.last;

  var index = scene.index;
  var opacity = position.interpolate({
    inputRange: [first, first + 0.01, index, last - 0.01, last],
    outputRange: [0, 1, 1, 0.85, 0]
  });

  var height = layout.initHeight;
  var translateY = position.interpolate({
    inputRange: [first, index, last],
    outputRange: [height, 0, 0]
  });
  var translateX = 0;

  return {
    opacity: opacity,
    transform: [{ translateX: translateX }, { translateY: translateY }]
  };
}

/**
 * Standard Android-style fade in from the bottom.
 */
function forFadeFromBottomAndroid(props) {
  var layout = props.layout,
      position = props.position,
      scene = props.scene;


  if (!layout.isMeasured) {
    return forInitial(props);
  }
  var interpolate = (0, _getSceneIndicesForInterpolationInputRange2.default)(props);

  if (!interpolate) return { opacity: 0 };

  var first = interpolate.first,
      last = interpolate.last;

  var index = scene.index;
  var inputRange = [first, index, last - 0.01, last];

  var opacity = position.interpolate({
    inputRange: inputRange,
    outputRange: [0, 1, 1, 0]
  });

  var translateY = position.interpolate({
    inputRange: inputRange,
    outputRange: [50, 0, 0, 0]
  });
  var translateX = 0;

  return {
    opacity: opacity,
    transform: [{ translateX: translateX }, { translateY: translateY }]
  };
}

/**
 *  fadeIn and fadeOut
 */
function forFade(props) {
  var layout = props.layout,
      position = props.position,
      scene = props.scene;


  if (!layout.isMeasured) {
    return forInitial(props);
  }
  var interpolate = (0, _getSceneIndicesForInterpolationInputRange2.default)(props);

  if (!interpolate) return { opacity: 0 };

  var first = interpolate.first,
      last = interpolate.last;

  var index = scene.index;
  var opacity = position.interpolate({
    inputRange: [first, index, last],
    outputRange: [0, 1, 1]
  });

  return {
    opacity: opacity
  };
}

function canUseNativeDriver() {
  // The native driver can be enabled for this interpolator animating
  // opacity, translateX, and translateY is supported by the native animation
  // driver on iOS and Android.
  return true;
}

exports.default = {
  forHorizontal: forHorizontal,
  forVertical: forVertical,
  forFadeFromBottomAndroid: forFadeFromBottomAndroid,
  forFade: forFade,
  canUseNativeDriver: canUseNativeDriver
};