Skip to content

Instantly share code, notes, and snippets.

@aamnah
Last active November 22, 2019 07:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aamnah/e1a33d592d173c6d8117baf997f39ad2 to your computer and use it in GitHub Desktop.
Save aamnah/e1a33d592d173c6d8117baf997f39ad2 to your computer and use it in GitHub Desktop.
Placeholder SVG component to indicate loading and wireframe application
/*
USAGE:
<Placeholder />
<Placeholder loading={false}/>
<Placeholder shape='circle' size={150}/>
<Placeholder shape='rect' width={200} height={100}/>
<Placeholder loading={false} shape='circle' size={100}/>
*/
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>
)
}
/*
LINKS:
https://tldrdevnotes.com/reactnative/loading-component-animated-animations/
https://tldrdevnotes.com/reactnative/svg-loading-component/
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment