react-native-shimmer-placeholder
Version:
<h2 align="center"> React Native Shimmer Placeholder </h2> <h5 align="center"> Placeholder for both IOS and Android </h5> <p align="center"> <img src="https://github.com/tomzaku/react-native-shimmer-placeholder/blob/master/example.gif?raw=true"> </p> <p
160 lines (154 loc) • 4.3 kB
JavaScript
// import liraries
import React, { Component } from 'react';
import PropTypes from 'prop-types'
import { View, StyleSheet, Animated, Platform } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
class CustomLinearGradient extends Component {
render() {
const { locationStart, colorShimmer, widthShimmer } = this.props;
return (
<LinearGradient
colors={colorShimmer}
style={{ flex: 1 }}
start={{
x: -1,
y: 0.5,
}}
end={{
x: 2,
y: 0.5,
}}
// locations={[0, 0.5, 1]}
locations={[locationStart + widthShimmer, locationStart + 0.5 + widthShimmer / 2, locationStart + 1]}
/>
);
}
}
CustomLinearGradient.propTypes = {
locationStart: PropTypes.any,
colorShimmer: PropTypes.array,
widthShimmer: PropTypes.number,
};
Animated.LinearGradient = Animated.createAnimatedComponent(CustomLinearGradient);
// create a component
class ShimmerPlaceHolder extends Component {
constructor(props) {
super(props);
// this.beginShimmerPosition = new Animated.Value(-1);
this.state = {
visible: false,
beginShimmerPosition: new Animated.Value(-1),
};
}
componentDidMount() {
const { autoRun } = this.props;
if (autoRun) {
this.loopAnimated();
}
}
loopAnimated() {
const shimmerAnimated = this.getAnimated();
const { visible } = this.props;
shimmerAnimated.start(() => {
if (!visible) {
this.loopAnimated();
}
})
}
getAnimated = () => {
// this.state.color.setValue(0);
this.state.beginShimmerPosition.setValue(-1);
return Animated.timing(this.state.beginShimmerPosition, {
toValue: 1,
duration: this.props.duration,
// useNativeDriver: true,
// easing: Easing.linear,
// delay: -400
});
}
render() {
const { width, reverse, height, colorShimmer, style, widthShimmer, children, visible, backgroundColorBehindBorder, hasBorder } = this.props;
let beginPostioner = -0.7;
let endPosition = 0.7;
if (reverse) {
beginPostioner = 0.7;
endPosition = -0.7;
}
const newValue = this.state.beginShimmerPosition.interpolate({
inputRange: [-1, 1],
outputRange: [beginPostioner, endPosition],
});
return (
<View style={!visible
? [{ height, width }, styles.container, style]
: []
}
>
{!visible
? (
<View style={{ flex: 1 }}>
<Animated.LinearGradient
locationStart={newValue}
colorShimmer={colorShimmer}
widthShimmer={widthShimmer}
/>
{/* Force run children */}
<View style={{ width: 0, height: 0 }}>
{this.props.children}
</View>
{((style && style.borderRadius) || hasBorder) && Platform.OS === 'android'
? <View style={{
position: 'absolute',
top: -40,
bottom: -40,
right: -40,
left: -40,
borderRadius: width / 2 + 40 / 2,
borderWidth: 40,
borderColor: backgroundColorBehindBorder,
}}
/>
: null }
</View>
)
: children
}
</View>
);
}
}
ShimmerPlaceHolder.defaultProps = {
width: 200,
height: 15,
widthShimmer: 0.7,
duration: 1000,
colorShimmer: ['#ebebeb', '#c5c5c5', '#ebebeb'],
reverse: false,
autoRun: false,
visible: false,
backgroundColorBehindBorder: 'white',
hasBorder: false,
};
// define your styles
const styles = StyleSheet.create({
container: {
// flex: 1,
overflow: 'hidden',
},
});
ShimmerPlaceHolder.propTypes = {
width: PropTypes.number,
height: PropTypes.number,
widthShimmer: PropTypes.number,
duration: PropTypes.number,
colorShimmer: PropTypes.array,
reverse: PropTypes.bool,
autoRun: PropTypes.bool,
visible: PropTypes.bool,
children: PropTypes.any,
style: PropTypes.any,
backgroundColorBehindBorder: PropTypes.string,
hasBorder: PropTypes.bool,
};
// make this component available to the app
export default ShimmerPlaceHolder;