Last active
November 22, 2019 07:27
-
-
Save aamnah/e1a33d592d173c6d8117baf997f39ad2 to your computer and use it in GitHub Desktop.
Placeholder SVG component to indicate loading and wireframe application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useEffect } from 'react' | |
import { Animated, View } from 'react-native' | |
import Svg, { | |
SvgProps, | |
Circle, | |
CircleProps, | |
Rect, | |
RectProps, | |
CommonPathProps | |
} from 'react-native-svg' | |
type Props = Readonly<{ | |
loading?: boolean | |
shape?: 'circle' | 'rect' | |
size: number | |
height: number | |
width: number | |
}> | |
// set a value to be animated | |
const currentColor = new Animated.Value(0) | |
// interpolate color value | |
const changeColor = currentColor.interpolate({ | |
inputRange: [0, 1, 2], // the values that the animation will transition from | |
outputRange: ['gainsboro', 'whitesmoke', 'gainsboro'] // values that are animating | |
}) | |
// define the looping animation | |
const animateColor = ()=> { | |
Animated.loop( | |
Animated.sequence([ | |
Animated.timing(currentColor, { | |
toValue: 2, // the value in interpolated output range that you want to go to | |
duration: 2000 // ms | |
}), | |
]) | |
).start() | |
} | |
export default function Placeholder({ | |
loading = true, | |
size = 50, | |
height = 50, | |
width = 50, | |
radius = 8, | |
shape = 'rect', | |
fill = 'gainsboro', | |
...rest | |
}: Props & | |
SvgProps & | |
CircleProps & | |
RectProps & | |
CommonPathProps & | |
any) { | |
useEffect(() => { | |
// start the animation to change background color | |
animateColor() | |
}) | |
const AnimatedSvg = Animated.createAnimatedComponent(Svg) | |
return ( | |
<View | |
loading={loading} | |
style={{margin: 8}} | |
{...rest} | |
> | |
{shape === 'circle' && ( | |
<AnimatedSvg | |
size={size} | |
height={size} | |
width={size} | |
viewBox={`0 0 ${size * 2} ${size * 2}`} | |
fill={loading ? changeColor : fill} | |
> | |
<Circle | |
cx={size} | |
cy={size} | |
r={size} | |
/> | |
</AnimatedSvg> | |
)} | |
{shape === 'rect' && ( | |
<AnimatedSvg | |
height={height} | |
width={width} | |
viewBox={`0 0 ${width} ${height}`} | |
fill={loading ? changeColor : fill} | |
> | |
<Rect | |
x="0" | |
y="0" | |
rx={radius} | |
width={width} | |
height={height} | |
/> | |
</AnimatedSvg> | |
)} | |
</View> | |
) | |
} | |
/* | |
USAGE: | |
<Placeholder /> | |
<Placeholder loading={false}/> | |
<Placeholder shape='circle' size={150}/> | |
<Placeholder shape='rect' width={200} height={100}/> | |
<Placeholder loading={false} shape='circle' size={100}/> | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment