Skip to content

Instantly share code, notes, and snippets.

@jeanverster
Created November 25, 2019 07:38
Show Gist options
  • Save jeanverster/8c03975e23abffb157a644e0c7a4b579 to your computer and use it in GitHub Desktop.
Save jeanverster/8c03975e23abffb157a644e0c7a4b579 to your computer and use it in GitHub Desktop.
import * as React from 'react'
import { Dimensions } from 'react-native'
import Animated from 'react-native-reanimated'
import Svg, { Path } from 'react-native-svg'
import { theme } from '../../theme'
import { BodyText, H1, H5 } from '../../typography'
import Box from '../Box'
import Card from '../Card'
export type PointsDialProps = {
progress: Animated.Node<number>
points: number
}
const { interpolate, multiply, sub, Value } = Animated
const { width } = Dimensions.get('window')
const size = width - 64
const strokeWidth = 20
const AnimatedPath = Animated.createAnimatedComponent(Path)
const { PI, cos, sin } = Math
const r = (size - strokeWidth) / 2
const cx = size / 2
const cy = size / 2
const A = PI + PI * 0.4
const startAngle = PI + PI * 0.2
const endAngle = 2 * PI - PI * 0.2
const x1 = cx - r * cos(startAngle)
const y1 = -r * sin(startAngle) + cy
const x2 = cx - r * cos(endAngle)
const y2 = -r * sin(endAngle) + cy
const d = `M ${x1} ${y1} A ${r} ${r} 0 1 0 ${x2} ${y2}`
const complete = new Value(1)
const PointsDial: React.FC<PointsDialProps> = ({ progress, points }) => {
const reverseProgress = sub(complete, progress)
const circumference = r * A
const α = interpolate(reverseProgress, {
inputRange: [0, 1],
outputRange: [0, -A]
})
const strokeDashoffset = multiply(α, r)
return (
<Card flexDirection="row" height={size} py={4} bg="background" justifyContent="center" alignItems="center">
<Svg width={size} height="100%">
<Path
fill="none"
strokeLinecap="round"
{...{ d, strokeWidth }}
stroke={theme.colors.muted}
strokeDasharray={`${circumference}, ${circumference}`}
/>
<AnimatedPath
fill="none"
strokeLinecap="round"
stroke={theme.colors.success}
{...{ d, strokeDashoffset, strokeWidth }}
strokeDasharray={`${circumference}, ${circumference}`}
/>
</Svg>
<Box position="absolute" alignItems="center">
<BodyText fontWeight="bold">Your Points</BodyText>
<H1 fontWeight="bold">{points}</H1>
</Box>
<Box alignSelf="flex-end" pb={4} position="absolute" alignItems="center">
<BodyText mb={1}>2000 points to the next level</BodyText>
<H5 fontWeight="bold">1.5x Multiplier</H5>
</Box>
</Card>
)
}
export default PointsDial
PointsDial.defaultProps = {
points: 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment