Skip to content

Instantly share code, notes, and snippets.

@mmazzarolo
Created December 7, 2019 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmazzarolo/4b65db01423546a8c12ed21b72b56412 to your computer and use it in GitHub Desktop.
Save mmazzarolo/4b65db01423546a8c12ed21b72b56412 to your computer and use it in GitHub Desktop.
Skipping the splash screen in Ordinary Puzzles
import React, { FC, useRef } from "react";
import { StyleSheet, Animated, TouchableWithoutFeedback } from "react-native";
import { Text } from "pg-common";
import { useAnimation, useOnMount, scale, delay } from "pg-utils";
import { animations, metrics, colors } from "pg-design";
import { credits } from "pg-config";
const asyncAnimationStart = (anim: Animated.CompositeAnimation) =>
new Promise(resolve => anim.start(resolve));
interface SplashProps {
onHide: () => void;
}
export const Splash: FC<SplashProps> = function({ onHide }) {
// Refs for keeping track of the skipping state of the screen
const skippingEnabledRef = useRef(true);
const hasSkippedRef = useRef(false);
// Animations setup
const fadeCreditsAnimDuration = 200;
const fadeCreditsStaggerDuration = 100;
const backgroundColorAnimDuration = 200;
const fadeCreditsAnims = credits.map(useAnimation);
const backgroundColorAnim = useAnimation();
const splashDuration = 2000;
const showAnim = Animated.stagger(
fadeCreditsStaggerDuration,
fadeCreditsAnims.map(anim =>
anim.setup({ duration: fadeCreditsAnimDuration })
)
);
const hideAnim = Animated.sequence([
Animated.stagger(
fadeCreditsStaggerDuration,
fadeCreditsAnims.map(anim =>
anim.setup({ duration: fadeCreditsAnimDuration, toValue: 0 })
)
),
backgroundColorAnim.setup({
duration: backgroundColorAnimDuration,
useNativeDriver: false
})
]);
// Animate the screen in and then out on mount
// If the screen has been tapped while the delay is
// running, don't animate-out (the out animation has been
// already triggered by the tap).
const animate = async () => {
await asyncAnimationStart(showAnim);
await delay(splashDuration);
skippingEnabledRef.current = false;
if (!hasSkippedRef.current) {
await asyncAnimationStart(hideAnim);
onHide();
}
};
useOnMount(() => {
animate();
});
const rootAnimStyle = {
backgroundColor: backgroundColorAnim.value.interpolate({
inputRange: [0, 1],
outputRange: [colors.splash, colors.primary[9]]
})
};
// If the user touches the screen, end the animation early
const handlePress = () => {
if (!skippingEnabledRef.current || hasSkippedRef.current) return;
hasSkippedRef.current = true;
hideAnim.start(onHide);
};
return (
<TouchableWithoutFeedback onPress={handlePress}>
<Animated.View style={[styles.root, rootAnimStyle]}>
{credits.map((credit, index) => (
<Text
key={credit}
weight="bold"
style={[
styles.credit,
animations.fadeSlideBottom(fadeCreditsAnims[index].value)
]}
>
{credit}
</Text>
))}
</Animated.View>
</TouchableWithoutFeedback>
);
};
const styles = StyleSheet.create({
root: {
padding: metrics.screenMargin,
flex: 1,
flexDirection: "column",
justifyContent: "center",
backgroundColor: colors.splash
},
credit: {
color: "white",
fontSize: scale(28),
marginVertical: scale(12)
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment