import React from 'react' ; import { Svg , Defs , LinearGradient , Stop , G , Circle , } from 'react-native-svg' ; import { StyleProp , ViewStyle , View , Animated , Text , TextStyle } from 'react-native' ; import { clamp } from 'common/utils/mathx' ; import Colors from 'src/constants/colors' ; import TextStyles from 'src/styles/TextStyles' ; const AnimatedContainer = Animated . createAnimatedComponent ( Circle ) ; type Props = { style ? : StyleProp < ViewStyle > ; progress : number ; diameter : number ; } ; const getOffset = ( d , progress ) => ( Math . round ( ( d * Math . PI ) * clamp ( 1 - progress / 4 , 0 , 1 ) ) ) ; export type GradColor = { title : string ; offset : number ; } ; type PropsGradient = Props & { title : string ; animationStep : number ; gradient ? : GradColor [ ] ; titleStyle ? : StyleProp < any > ; } ; export default function ProgressBarHaflCircle ( this , props ) { const { animationStep , title , diameter , gradient , progress , style , titleStyle } = props ; const length = Math . round ( diameter * Math . PI ) ; const [ offset ] = React . useState ( ( ) => { const startProgress = ( progress - ( animationStep || 0.1 ) ) ; return new Animated . Value ( getOffset ( diameter , startProgress ) ) ; } ) ; React . useEffect ( ( ) => { Animated . timing ( offset , { toValue : getOffset ( diameter , progress ) , duration : 2000 , delay : 750 , } ) . start ( ) ; } , [ progress ] ) ; const boxSize = diameter + 6 ; const origin = diameter / 2 ; const defaultTitleStyles = { position : 'absolute' , alignItems : 'center' , justifyContent : 'center' , } ; return ( < View style = { style } > < Text style = { [ TextStyles . p3 , defaultTitleStyles , titleStyle ] } > { title } < /Text> < Svg id = "progress-bar-circle" width = "100%" height = "100%" viewBox = { `0 0 ${ boxSize } ${ boxSize }` } fill = "none" > < G x = { 3 } y = { 3 } > < Circle id = "circle-bg" opacity = "0.2" cx = { diameter / 2 } cy = { diameter / 2 } r = { diameter / 2 } strokeWidth = "3" stroke = "url(#paint0_linear)" fill = "none" / > < AnimatedContainer id = "circle-progress" fill = "none" cx = { diameter / 2 } cy = { diameter / 2 } r = { diameter / 2 } strokeWidth = "3" stroke = "url(#paint0_linear)" strokeDasharray = { length } strokeDashoffset = { offset } origin = { `${ origin }, ${ origin }` } rotation = { 90 } / > < AnimatedContainer id = "circle-progress2" fill = "none" cx = { diameter / 2 } cy = { diameter / 2 } r = { diameter / 2 } strokeWidth = "3" stroke = "url(#paint0_linear)" strokeDasharray = { length } strokeDashoffset = { offset } origin = { `${ origin }, ${ origin }` } scaleX = { - 1 } rotation = { - 90 } /> < /G> < Defs > { gradient ? ( < LinearGradient id = "paint0_linear" x1 = { diameter / 2 } y1 = { diameter } x2 = { diameter } y2 = { 0 } gradientUnits = "userSpaceOnUse" > { gradient . map ( ( color , i ) => { return < Stop key = { `${ color . title }_${ i }` } offset = { color . offset } stopColor = { color . title } / > ; } ) } < /LinearGradient>) : (<LinearGradient id="paint0_linear" x1={0} y1={diameter / 2 } x2 = { diameter } y2 = { diameter / 2 } gradientUnits = "userSpaceOnUse" > < Stop offset = "0.0996095" stopColor = "#FFCECF" / > < Stop offset = "0.238673" stopColor = "#9A87E7" / > < Stop offset = "0.384948" stopColor = "#FFAFD5" / > < Stop offset = "0.512681" stopColor = "#FA8989" / > < Stop offset = "0.642474" stopColor = "#CFC4FF" / > < Stop offset = "0.776388" stopColor = "#FFAFD5" / > < Stop offset = "0.90206" stopColor = "#FFCED0" / > < /LinearGradient>)} < /Defs> < /Svg> < /View>); }