React Navigation源代码阅读 : views/CardStack/TransitionConfigs.js

import {Animated, Easing, Platform} from 'react-native';
import CardStackStyleInterpolator from './CardStackStyleInterpolator';
import * as ReactNativeFeatures from '../../utils/ReactNativeFeatures';

/**
* 根据不同平台上的缺省行为的不同,为iOS或者Android定义不同的屏幕过渡动画设置, 
* 可以将每个屏幕过渡动画设置抽象理解为定义的一个类 TransitionConfig, 下面
* 给出了一个这样的实例方便理解 : 
* {
*   transitionSpec : { // 屏幕过渡动画规格定义
*       duration: 500,
*       easing: Easing.bezier(0.2833, 0.99, 0.31833, 0.99),
*       timing: Animated.timing,        
*   },
*   screenInterpolator :  { // 屏幕切换插值器
*       CardStackStyleInterpolator.forVertical,
*   },
*   containerStyle : { // 此属性在该文件中仅针对iOS平台使用,针对Android平台没有使用
*       backgroundColor: '#000',
*   }
* }
**/

let IOSTransitionSpec;
if (ReactNativeFeatures.supportsImprovedSpringAnimation()) {
    // These are the exact values from UINavigationController's animation configuration
    IOSTransitionSpec = {
        timing: Animated.spring,
        stiffness: 1000,
        damping: 500,
        mass: 3,
    };
} else {
    // This is an approximation of the IOS spring animation using a derived bezier curve
    IOSTransitionSpec = {
        duration: 500,
        easing: Easing.bezier(0.2833, 0.99, 0.31833, 0.99),
        timing: Animated.timing,
    };
}

// Standard iOS navigation transition
const SlideFromRightIOS = {
    transitionSpec: IOSTransitionSpec,
    screenInterpolator: CardStackStyleInterpolator.forHorizontal,
    containerStyle: {
        backgroundColor: '#000',
    },
};

// Standard iOS navigation transition for modals
const ModalSlideFromBottomIOS = {
    transitionSpec: IOSTransitionSpec,
    screenInterpolator: CardStackStyleInterpolator.forVertical,
    containerStyle: {
        backgroundColor: '#000',
    },
};

// Standard Android navigation transition when opening an Activity
// 安卓平台上出现一个新屏幕时缺省使用的过渡方式
const FadeInFromBottomAndroid = {
// http://androidxref.com/7.1.1_r6/xref/frameworks/base/core/res/res/anim/activity_open_enter.xml
    transitionSpec: {
        duration: 350, // 安卓平台上,修改此值,或者覆盖此值,可以对屏幕出现动画进行加速或者减速
        easing: Easing.out(Easing.poly(5)), // decelerate
        timing: Animated.timing,
    },
    screenInterpolator: CardStackStyleInterpolator.forFadeFromBottomAndroid,
};

// Standard Android navigation transition when closing an Activity
// 安卓平台上关闭一个新屏幕时缺省使用的过渡方式 (比如返回)
const FadeOutToBottomAndroid = {
// http://androidxref.com/7.1.1_r6/xref/frameworks/base/core/res/res/anim/activity_close_exit.xml
    transitionSpec: {
        duration: 230, // 安卓平台上,修改此值,或者覆盖此值,可以对屏幕关闭动画进行加速或者减速
        easing: Easing.in(Easing.poly(4)), // accelerate
        timing: Animated.timing,
    },
    screenInterpolator: CardStackStyleInterpolator.forFadeFromBottomAndroid,
};

/**
 * 缺省屏幕切换过渡动画配置,没有考虑开发人员的设置,使用react-navigation预定义配置
 * @param transitionProps
 * @param prevTransitionProps
 * @param isModal
 * @returns {*}
 */
function defaultTransitionConfig(
    // props for the new screen
    transitionProps,
    // props for the old screen
    prevTransitionProps,
    // whether we're animating in/out a modal screen
    isModal
) {
    if (Platform.OS === 'android') {
        // Use the default Android animation no matter if the screen is a modal.
        // Android doesn't have full-screen modals like iOS does, it has dialogs.
        if (
            prevTransitionProps &&
            transitionProps.index < prevTransitionProps.index
        ) {
            // Navigating back to the previous screen
            return FadeOutToBottomAndroid;
        }
        return FadeInFromBottomAndroid;
    }
    // iOS and other platforms
    if (isModal) {
        return ModalSlideFromBottomIOS;
    }
    return SlideFromRightIOS;
}

/**
 * 构建和返回屏幕切换过渡动画配置,基于缺省屏幕切换过渡动画配置,考虑了开发人员的自定义设置
 * @param transitionConfigurer 开发人员指定的设置函数,函数签名如下:
 * func(transitionProps, prevTransitionProps, isModal):TransitionConfig
 * @param transitionProps
 * @param prevTransitionProps
 * @param isModal
 */
function getTransitionConfig(
    transitionConfigurer,
    // props for the new screen
    transitionProps,
    // props for the old screen
    prevTransitionProps,
    isModal
) {
    // 先基于 transitionProps ,prevTransitionProps ,isModal 构建缺省配置对象defaultConfig
    const defaultConfig = defaultTransitionConfig(
        transitionProps,
        prevTransitionProps,
        isModal
    );

    if (transitionConfigurer) {
        // 如果指定了配置器函数 transitionConfigurer ,使用 transitionConfigurer 构建一个配置对象,
        // 并将该配置对象覆盖到上面创建的缺省配置对象 defaultConfig 上,然会合并后的配置对象
        return {
            ...defaultConfig,
            ...transitionConfigurer(transitionProps, prevTransitionProps, isModal),
        };
    }
    // 如果没有指定配置器函数 transitionConfigurer,直接返回缺省配置对象 defaultConfig
    return defaultConfig;
}

export default {
    defaultTransitionConfig,
    getTransitionConfig,
};

猜你喜欢

转载自blog.csdn.net/andy_zhang2007/article/details/80380860