react-native-onboarding-flow
Version:
Beautiful, customizable onboarding flows for React Native with smooth animations
179 lines (176 loc) • 7.39 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const react_native_1 = require("react-native");
const expo_av_1 = require("expo-av");
const animations_1 = require("../animations");
const { width, height } = react_native_1.Dimensions.get('window');
const OnboardingSlide = ({ slide, isActive, theme }) => {
const mediaOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
const titleOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
const descriptionOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
const titleTranslateY = (0, react_1.useRef)(new react_native_1.Animated.Value(30)).current;
const descriptionTranslateY = (0, react_1.useRef)(new react_native_1.Animated.Value(30)).current;
const mediaScale = (0, react_1.useRef)(new react_native_1.Animated.Value(0.8)).current;
const mediaData = slide.media;
(0, react_1.useEffect)(() => {
if (isActive) {
mediaOpacity.setValue(0);
titleOpacity.setValue(0);
descriptionOpacity.setValue(0);
titleTranslateY.setValue(30);
descriptionTranslateY.setValue(30);
mediaScale.setValue(0.8);
const animations = [];
const animationType = slide.animation || 'fadeIn';
if (animationType === 'scaleIn') {
animations.push((0, animations_1.createScaleInAnimation)(mediaScale, 600, 200));
animations.push((0, animations_1.createFadeInAnimation)(mediaOpacity, 400, 200));
}
else {
animations.push((0, animations_1.createFadeInAnimation)(mediaOpacity, 500, 200));
animations.push((0, animations_1.createScaleInAnimation)(mediaScale, 400, 200));
}
animations.push((0, animations_1.createFadeInAnimation)(titleOpacity, 400, 600));
animations.push((0, animations_1.createSlideUpAnimation)(titleTranslateY, 400, 600));
animations.push((0, animations_1.createFadeInAnimation)(descriptionOpacity, 400, 800));
animations.push((0, animations_1.createSlideUpAnimation)(descriptionTranslateY, 400, 800));
react_native_1.Animated.parallel(animations).start();
}
}, [isActive]);
const renderMedia = () => {
const defaultSize = Math.min(width * 0.6, height * 0.3);
const mediaStyle = [
styles.media,
{
width: mediaData.width || defaultSize,
height: mediaData.height || defaultSize,
maxWidth: width * 0.8,
maxHeight: height * 0.35,
opacity: mediaOpacity,
transform: [{ scale: mediaScale }],
borderRadius: mediaData.borderRadius,
overflow: 'hidden',
},
];
if (mediaData.type === 'video') {
const videoStyle = [
styles.video,
{
borderRadius: mediaData.borderRadius || 12,
},
];
return (<react_native_1.Animated.View style={mediaStyle}>
<expo_av_1.Video source={mediaData.source} style={videoStyle} resizeMode={expo_av_1.ResizeMode.CONTAIN} shouldPlay={isActive && (mediaData.autoPlay !== false)} isLooping={mediaData.loop !== false} isMuted={mediaData.muted !== false} onError={(error) => console.log('Video load error:', error)}/>
</react_native_1.Animated.View>);
}
return (<react_native_1.Animated.Image source={mediaData.source} style={mediaStyle} resizeMode="contain" onError={(error) => console.log('Image load error:', error)}/>);
};
return (<react_native_1.View style={styles.container}>
<react_native_1.View style={styles.mediaContainer}>
{renderMedia()}
</react_native_1.View>
<react_native_1.ScrollView style={styles.textContainer} contentContainerStyle={styles.textContentContainer} showsVerticalScrollIndicator={false} bounces={false}>
<react_native_1.Animated.Text style={[
styles.title,
{ color: (theme === null || theme === void 0 ? void 0 : theme.titleColor) || '#2F4F2F' },
{
opacity: titleOpacity,
transform: [{ translateY: titleTranslateY }],
},
]}>
{slide.title}
</react_native_1.Animated.Text>
<react_native_1.Animated.Text style={[
styles.description,
{ color: (theme === null || theme === void 0 ? void 0 : theme.descriptionColor) || '#666' },
{
opacity: descriptionOpacity,
transform: [{ translateY: descriptionTranslateY }],
},
]}>
{slide.description}
</react_native_1.Animated.Text>
</react_native_1.ScrollView>
</react_native_1.View>);
};
const styles = react_native_1.StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
paddingHorizontal: 40,
paddingTop: 20,
},
mediaContainer: {
justifyContent: 'center',
alignItems: 'center',
width: '100%',
maxHeight: height * 0.35,
minHeight: height * 0.25,
marginBottom: 30,
},
media: {
// Size is now controlled by mediaStyle in renderMedia()
},
video: {
width: '100%',
height: '100%',
borderRadius: 12,
},
textContainer: {
flex: 1,
width: '100%',
},
textContentContainer: {
alignItems: 'center',
paddingBottom: 20,
flexGrow: 1,
},
title: {
fontSize: 28,
fontWeight: '700',
textAlign: 'center',
marginBottom: 16,
lineHeight: 34,
},
description: {
fontSize: 16,
textAlign: 'center',
lineHeight: 24,
paddingHorizontal: 20,
},
});
exports.default = OnboardingSlide;