The React Native component, crawl.tsx, is designed to bring the iconic Star Wars opening crawl animation to life in mobile applications and on the web. Utilizing the Animated library, it features a sequence of animations including fading, scaling, and translating elements within a modal. The component dynamically displays a provided opening crawl text with cinematic effects: a fade-in and fade-out introduction text ("A long time ago in a galaxy far, far away..."), a scaling and fading logo animation, a scrolling and tilted crawl text animation with customizable content, and a starry background image for immersion. Styled using StyleSheet, it supports responsive design with Dimensions. This component demonstrates expertise in React Native animations, dynamic content handling, and creative UI design. And I just had to do it. I hope you enjoy being able to watch the opening crawl of the Star Wars films in the palm of your hand.
useEffect(() => {
// Sequence of animations
Animated.sequence([
// Step 1: Fade in the View with texts
Animated.timing(viewOpacity, {
toValue: 1,
duration: 1000, // 1 second fade-in
useNativeDriver: true,
}),
Animated.timing(viewOpacity, {
toValue: 0,
duration: 1000, // 1 second fade-out after 5 seconds
delay: 4000, // Wait for 4 seconds before fading out
useNativeDriver: true,
}),
// Step 2: Scale and fade in the logo
Animated.parallel([
Animated.timing(logoOpacity, {
toValue: 1,
duration: 1000, // 1 second fade-in
useNativeDriver: true,
}),
Animated.timing(logoScale, {
toValue: 0.05, // Shrink to 1/20th of the size
duration: 12000, // 10 seconds
useNativeDriver: true,
}),
]),
// Step 3: Fade out the logo
Animated.timing(logoOpacity, {
toValue: 0,
duration: 1000, // 1 second fade-out
useNativeDriver: true,
}),
]).start();
// Step 4: Animate the crawl text
Animated.parallel([
Animated.timing(translateY, {
toValue: -1000, // Move the text far up
duration: 70000, // Duration of the animation (70 seconds)
delay: 4000, // Delay before starting the crawl
useNativeDriver: true,
}),
// Animated.timing(crawlScale, {
// toValue: 0.5, // Shrink to 50% of the original size
// duration: 70000, // Match the duration of the crawl
// delay: 8000, // Delay before starting the crawl
// useNativeDriver: true,
// }),
]).start();
}, [viewOpacity, logoScale, logoOpacity, translateY, crawlScale]);