UNPKG

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
// 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;