Skip to content

Instantly share code, notes, and snippets.

@tronghieu60s
Last active May 30, 2024 14:12
Show Gist options
  • Save tronghieu60s/187cc7b982b25d4817331d684af538c5 to your computer and use it in GitHub Desktop.
Save tronghieu60s/187cc7b982b25d4817331d684af538c5 to your computer and use it in GitHub Desktop.
/**
* Design belike this video:
* https://youtu.be/zM3l9jpt5PU
*/
import React, {useEffect} from 'react';
import {Animated, Dimensions, Easing, StyleSheet, View as DefaultView} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
const width = Dimensions.get('window').width;
const AnimatedNewLG = Animated.createAnimatedComponent(LinearGradient);
type Props = {
style?: DefaultView['props']['style'];
speed?: number;
backgroundColor?: string;
highlightColor?: string;
};
export default function Skeleton(props: Props) {
const {
style = {},
speed = 1000,
backgroundColor = '#E1E9EE',
highlightColor = '#F2F8FC',
} = props;
const animatedValue = new Animated.Value(0);
useEffect(() => {
let currentSpeed = speed;
if (speed < 300) {
currentSpeed = 300;
}
Animated.loop(
Animated.timing(animatedValue, {
toValue: 1,
duration: currentSpeed,
easing: Easing.linear,
useNativeDriver: true,
}),
).start();
});
const translateX = animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, width],
});
return (
<DefaultView style={[{overflow: 'hidden', backgroundColor}, style]}>
<AnimatedNewLG
colors={[
backgroundColor,
highlightColor,
backgroundColor,
highlightColor,
]}
start={{x: 0, y: 0}}
end={{x: 1, y: 0}}
style={{...StyleSheet.absoluteFillObject, transform: [{translateX}]}}
/>
</DefaultView>
);
}
@tronghieu60s
Copy link
Author

tronghieu60s commented May 30, 2024

Skeleton for OCD user 😒

import React, { useEffect } from "react";
import {
  Animated,
  Dimensions,
  Easing,
  StyleSheet,
  View as DefaultView,
  ViewProps,
} from "react-native";
import LinearGradient from "react-native-linear-gradient";

const width = Dimensions.get("window").width;
const AnimatedNewLG = Animated.createAnimatedComponent(LinearGradient);

type Props = ViewProps & {
  speed?: number;
  highlightColor?: string;
  backgroundColor?: string;
};

export default function Skeleton(props: Props) {
  const {
    style,
    speed = 1000,
    highlightColor = "#F2F8FC",
    backgroundColor = "#E1E9EE",
    ...restProps
  } = props;

  const animatedValue = new Animated.Value(0);

  useEffect(() => {
    let currentSpeed = speed;
    if (speed < 300) {
      currentSpeed = 300;
    }
    Animated.loop(
      Animated.timing(animatedValue, {
        toValue: 1,
        duration: currentSpeed,
        easing: Easing.linear,
        useNativeDriver: true,
      }),
    ).start();
  });

  const translateX = animatedValue.interpolate({
    inputRange: [0, 1],
    outputRange: [0, width],
  });

  return (
    <DefaultView {...restProps} style={[{ overflow: "hidden", backgroundColor }, style]}>
      <AnimatedNewLG
        colors={[backgroundColor, highlightColor, backgroundColor, highlightColor]}
        start={{ x: 0, y: 0 }}
        end={{ x: 1, y: 0 }}
        style={{ ...StyleSheet.absoluteFillObject, transform: [{ translateX }] }}
      />
    </DefaultView>
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment