@react-navigation/stack
Version:
Stack navigator component for iOS and Android with animated transitions and gestures
361 lines (352 loc) • 8.89 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.forBottomSheetAndroid = forBottomSheetAndroid;
exports.forFadeFromBottomAndroid = forFadeFromBottomAndroid;
exports.forFadeFromCenter = forFadeFromCenter;
exports.forHorizontalIOS = forHorizontalIOS;
exports.forModalPresentationIOS = forModalPresentationIOS;
exports.forNoAnimation = forNoAnimation;
exports.forRevealFromBottomAndroid = forRevealFromBottomAndroid;
exports.forScaleFromCenterAndroid = forScaleFromCenterAndroid;
exports.forVerticalIOS = forVerticalIOS;
var _reactNative = require("react-native");
var _conditional = _interopRequireDefault(require("../utils/conditional"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const {
add,
multiply
} = _reactNative.Animated;
/**
* Standard iOS-style slide in from the right.
*/
function forHorizontalIOS(_ref) {
let {
current,
next,
inverted,
layouts: {
screen
}
} = _ref;
const translateFocused = multiply(current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.width, 0],
extrapolate: 'clamp'
}), inverted);
const translateUnfocused = next ? multiply(next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, screen.width * -0.3],
extrapolate: 'clamp'
}), inverted) : 0;
const overlayOpacity = current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 0.07],
extrapolate: 'clamp'
});
const shadowOpacity = current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 0.3],
extrapolate: 'clamp'
});
return {
cardStyle: {
transform: [
// Translation for the animation of the current card
{
translateX: translateFocused
},
// Translation for the animation of the card on top of this
{
translateX: translateUnfocused
}]
},
overlayStyle: {
opacity: overlayOpacity
},
shadowStyle: {
shadowOpacity
}
};
}
/**
* Standard iOS-style slide in from the bottom (used for modals).
*/
function forVerticalIOS(_ref2) {
let {
current,
inverted,
layouts: {
screen
}
} = _ref2;
const translateY = multiply(current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.height, 0],
extrapolate: 'clamp'
}), inverted);
return {
cardStyle: {
transform: [{
translateY
}]
}
};
}
/**
* Standard iOS-style modal animation in iOS 13.
*/
function forModalPresentationIOS(_ref3) {
let {
index,
current,
next,
inverted,
layouts: {
screen
},
insets
} = _ref3;
const hasNotchIos = _reactNative.Platform.OS === 'ios' && !_reactNative.Platform.isPad && !_reactNative.Platform.isTV && insets.top > 20;
const isLandscape = screen.width > screen.height;
const topOffset = isLandscape ? 0 : 10;
const statusBarHeight = insets.top;
const aspectRatio = screen.height / screen.width;
const progress = add(current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp'
}), next ? next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp'
}) : 0);
const isFirst = index === 0;
const translateY = multiply(progress.interpolate({
inputRange: [0, 1, 2],
outputRange: [screen.height, isFirst ? 0 : topOffset, (isFirst ? statusBarHeight : 0) - topOffset * aspectRatio]
}), inverted);
const overlayOpacity = progress.interpolate({
inputRange: [0, 1, 1.0001, 2],
outputRange: [0, 0.3, 1, 1]
});
const scale = isLandscape ? 1 : progress.interpolate({
inputRange: [0, 1, 2],
outputRange: [1, 1, screen.width ? 1 - topOffset * 2 / screen.width : 1]
});
const borderRadius = isLandscape ? 0 : isFirst ? progress.interpolate({
inputRange: [0, 1, 1.0001, 2],
outputRange: [0, 0, hasNotchIos ? 38 : 0, 10]
}) : 10;
return {
cardStyle: {
overflow: 'hidden',
borderTopLeftRadius: borderRadius,
borderTopRightRadius: borderRadius,
// We don't need these for the animation
// But different border radius for corners improves animation perf
borderBottomLeftRadius: hasNotchIos ? borderRadius : 0,
borderBottomRightRadius: hasNotchIos ? borderRadius : 0,
marginTop: isFirst ? 0 : statusBarHeight,
marginBottom: isFirst ? 0 : topOffset,
transform: [{
translateY
}, {
scale
}]
},
overlayStyle: {
opacity: overlayOpacity
}
};
}
/**
* Standard Android-style fade in from the bottom for Android Oreo.
*/
function forFadeFromBottomAndroid(_ref4) {
let {
current,
inverted,
layouts: {
screen
},
closing
} = _ref4;
const translateY = multiply(current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.height * 0.08, 0],
extrapolate: 'clamp'
}), inverted);
const opacity = (0, _conditional.default)(closing, current.progress, current.progress.interpolate({
inputRange: [0, 0.5, 0.9, 1],
outputRange: [0, 0.25, 0.7, 1],
extrapolate: 'clamp'
}));
return {
cardStyle: {
opacity,
transform: [{
translateY
}]
}
};
}
/**
* Standard Android-style reveal from the bottom for Android Pie.
*/
function forRevealFromBottomAndroid(_ref5) {
let {
current,
next,
inverted,
layouts: {
screen
}
} = _ref5;
const containerTranslateY = multiply(current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.height, 0],
extrapolate: 'clamp'
}), inverted);
const cardTranslateYFocused = multiply(current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.height * (95.9 / 100) * -1, 0],
extrapolate: 'clamp'
}), inverted);
const cardTranslateYUnfocused = next ? multiply(next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, screen.height * (2 / 100) * -1],
extrapolate: 'clamp'
}), inverted) : 0;
const overlayOpacity = current.progress.interpolate({
inputRange: [0, 0.36, 1],
outputRange: [0, 0.1, 0.1],
extrapolate: 'clamp'
});
return {
containerStyle: {
overflow: 'hidden',
transform: [{
translateY: containerTranslateY
}]
},
cardStyle: {
transform: [{
translateY: cardTranslateYFocused
}, {
translateY: cardTranslateYUnfocused
}]
},
overlayStyle: {
opacity: overlayOpacity
}
};
}
/**
* Standard Android-style zoom for Android 10.
*/
function forScaleFromCenterAndroid(_ref6) {
let {
current,
next,
closing
} = _ref6;
const progress = add(current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp'
}), next ? next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp'
}) : 0);
const opacity = progress.interpolate({
inputRange: [0, 0.75, 0.875, 1, 1.0825, 1.2075, 2],
outputRange: [0, 0, 1, 1, 1, 1, 0]
});
const scale = (0, _conditional.default)(closing, current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0.925, 1],
extrapolate: 'clamp'
}), progress.interpolate({
inputRange: [0, 1, 2],
outputRange: [0.85, 1, 1.075]
}));
return {
cardStyle: {
opacity,
transform: [{
scale
}]
}
};
}
/**
* Standard bottom sheet slide in from the bottom for Android.
*/
function forBottomSheetAndroid(_ref7) {
let {
current,
inverted,
layouts: {
screen
},
closing
} = _ref7;
const translateY = multiply(current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.height * 0.8, 0],
extrapolate: 'clamp'
}), inverted);
const opacity = (0, _conditional.default)(closing, current.progress, current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp'
}));
const overlayOpacity = current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 0.3],
extrapolate: 'clamp'
});
return {
cardStyle: {
opacity,
transform: [{
translateY
}]
},
overlayStyle: {
opacity: overlayOpacity
}
};
}
/**
* Simple fade animation for dialogs
*/
function forFadeFromCenter(_ref8) {
let {
current: {
progress
}
} = _ref8;
return {
cardStyle: {
opacity: progress.interpolate({
inputRange: [0, 0.5, 0.9, 1],
outputRange: [0, 0.25, 0.7, 1]
})
},
overlayStyle: {
opacity: progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 0.5],
extrapolate: 'clamp'
})
}
};
}
function forNoAnimation() {
return {};
}
//# sourceMappingURL=CardStyleInterpolators.js.map