| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- import React, { memo, useMemo } from 'react';
- import { StyleSheet, View } from 'react-native';
- import Animated, {
- useSharedValue,
- withRepeat,
- withTiming,
- useAnimatedReaction,
- useDerivedValue,
- useAnimatedStyle,
- Easing,
- } from 'react-native-reanimated';
- import { useLayout, useGetBones } from 'react-native-reanimated-skeleton/lib/hooks';
- import TextView from './TextView';
- export const ANIMATION_TYPE = {
- NONE: "none",
- SHIVER: "shiver",
- PULSE: "pulse"
- }
- export const ANIMATION_DIRECTION = {
- HORIZONTAL_LEFT: "horizontalLeft",
- HORIZONTAL_RIGHT: "horizontalRight",
- VERTICAL_TOP: "verticalTop",
- VERTICAL_DOWN: "verticalDown",
- DIAGONAL_DOWN_LEFT: "diagonalDownLeft",
- DIAGONAL_DOWN_RIGHT: "diagonalDownRight",
- DIAGONAL_TOP_LEFT: "diagonalTopLeft",
- DIAGONAL_TOP_RIGHT: "diagonalTopRight"
- }
- const VbeSkeleton = ({
- style=styles.container,
- viewStyle={},
- textStyle={},
- text,
- duration=1200,
- layout=[],
- numberOfLines,
- animationType=ANIMATION_TYPE.SHIVER,
- animationDirection=ANIMATION_DIRECTION.HORIZONTAL_LEFT,
- easing=Easing.bezier(0.5, 0, 0.25, 1),
- isLoading=true,
- boneColor='#eeeeee',
- highlightColor='#f6f6f6',
- hasFadeIn=false,
- children
- }) => {
- const animationValue = useSharedValue(0);
- const loadingValue = useSharedValue(0);
- const shiverValue = useSharedValue(animationType === 'shiver' ? 1 : 0);
- const [componentSize, onLayout] = useLayout();
- const generalStyles = useMemo(
- () => ({
- animationDirection,
- animationType,
- boneColor,
- animationValue,
- highlightColor,
- }),
- [
- animationDirection,
- animationType,
- animationValue,
- boneColor,
- highlightColor,
- ],
- );
- const getBones = useGetBones(componentSize);
- useAnimatedReaction(
- () => ({ isLoading, loadingValue }),
- () => {
- if (isLoading && loadingValue.value !== 1) {
- /* NOTE: Reset behaviour to ensure animation always starts from the beginning */
- animationValue.value = 0;
- animationValue.value =
- shiverValue.value === 1
- ? withRepeat(withTiming(1, { duration, easing }), -1, false)
- : withRepeat(
- withTiming(1, { duration: duration / 2, easing }),
- -1,
- true,
- );
- }
- },
- [isLoading, shiverValue],
- );
- const opacity = useDerivedValue(() => {
- if (!isLoading) {
- return withTiming(1, { duration: 250 });
- }
- return 0;
- });
- const animatedStyle = useAnimatedStyle(() => ({
- opacity: opacity.value,
- }));
- return (
- <View style={style} onLayout={onLayout}>
- {isLoading ? (
- getBones({
- bonesLayout: layout,
- children,
- generalStyles,
- })
- ) : (
- <Animated.View style={[viewStyle, hasFadeIn ? animatedStyle : {}]}>
- { text
- ? <TextView style={textStyle} numberOfLines={numberOfLines}>{text}</TextView>
- : children
- }
- </Animated.View>
- )}
- </View>
- );
- };
- export default VbeSkeleton;
- const styles = StyleSheet.create({
- container: {
- flex: 1,
- alignItems: 'center',
- justifyContent: 'center'
- },
- viewStyle: {
- alignItems: 'center'
- }
- });
|