react-native-spotlight-tour
Version:
React Native library to implement a highly customizable app tour feature with an awesome spotlight effect
121 lines (106 loc) • 2.71 kB
text/typescript
import { Animated, type LayoutRectangle, type MeasureInWindowOnSuccessCallback } from "react-native";
import type { Motion } from "../lib/SpotlightTour.context";
interface RefNode {
measure: (callback: MeasureInWindowOnSuccessCallback) => void;
}
export interface ShapeProps {
motion: Motion;
padding: number;
setReference: (node?: RefNode) => void;
spot: LayoutRectangle;
useNativeDriver: boolean;
}
interface Point {
x: number;
y: number;
}
interface BaseTransitionOptions {
motion: Motion;
nextOrigin: Point;
opacity: Animated.Value;
origin: Animated.ValueXY;
useNativeDriver: boolean;
}
interface ValueTransitionOptions extends BaseTransitionOptions {
nextSize: number;
size: Animated.Value;
}
interface PointTransitionOptions extends BaseTransitionOptions {
nextSize: Point;
size: Animated.ValueXY;
}
type TransitionOptions = PointTransitionOptions | ValueTransitionOptions;
export function transitionOf(options: TransitionOptions): Animated.CompositeAnimation {
const {
motion,
nextOrigin,
nextSize,
opacity,
origin,
size,
useNativeDriver,
} = options;
switch (motion) {
case "bounce":
opacity.setValue(1);
return Animated.parallel([
Animated.spring(origin, {
damping: 45,
mass: 4,
restDisplacementThreshold: 0.0875,
restSpeedThreshold: 1000,
stiffness: 350,
toValue: nextOrigin,
useNativeDriver,
}),
Animated.spring(size, {
damping: 45,
mass: 4,
restDisplacementThreshold: 0.0875,
restSpeedThreshold: 1000,
stiffness: 350,
toValue: nextSize,
useNativeDriver,
}),
]);
case "fade":
return Animated.sequence([
Animated.timing(opacity, {
duration: 400,
toValue: 0,
useNativeDriver,
}),
Animated.parallel([
Animated.timing(origin, {
duration: 0,
toValue: nextOrigin,
useNativeDriver,
}),
Animated.timing(size, {
duration: 0,
toValue: nextSize,
useNativeDriver,
}),
]),
Animated.timing(opacity, {
duration: 400,
toValue: 1,
useNativeDriver,
}),
]);
case "slide":
opacity.setValue(1);
return Animated.parallel([
Animated.timing(origin, {
duration: 400,
toValue: nextOrigin,
useNativeDriver,
}),
Animated.timing(size, {
duration: 400,
toValue: nextSize,
useNativeDriver,
}),
]);
}
}