Bluesky app fork with some witchin' additions 馃挮
at post-text-option 96 lines 2.2 kB view raw
1import React from 'react' 2import Animated, { 3 Easing, 4 useAnimatedProps, 5 useSharedValue, 6 withDelay, 7 withTiming, 8} from 'react-native-reanimated' 9import Svg, {Circle, Path} from 'react-native-svg' 10 11import {type Props, useCommonSVGProps} from '#/components/icons/common' 12 13const AnimatedPath = Animated.createAnimatedComponent(Path) 14const AnimatedCircle = Animated.createAnimatedComponent(Circle) 15 16const PATH = 'M14.1 27.2l7.1 7.2 16.7-16.8' 17 18export interface AnimatedCheckRef { 19 play(cb?: () => void): void 20} 21 22export interface AnimatedCheckProps extends Props { 23 playOnMount?: boolean 24} 25 26export const AnimatedCheck = React.forwardRef< 27 AnimatedCheckRef, 28 AnimatedCheckProps 29>(function AnimatedCheck({playOnMount, ...props}, ref) { 30 const {fill, size, style, ...rest} = useCommonSVGProps(props) 31 const circleAnim = useSharedValue(0) 32 const checkAnim = useSharedValue(0) 33 34 const circleAnimatedProps = useAnimatedProps(() => ({ 35 strokeDashoffset: 166 - circleAnim.get() * 166, 36 })) 37 const checkAnimatedProps = useAnimatedProps(() => ({ 38 strokeDashoffset: 48 - 48 * checkAnim.get(), 39 })) 40 41 const play = React.useCallback( 42 (cb?: () => void) => { 43 circleAnim.set(0) 44 checkAnim.set(0) 45 46 circleAnim.set(() => 47 withTiming(1, {duration: 500, easing: Easing.linear}), 48 ) 49 checkAnim.set(() => 50 withDelay( 51 500, 52 withTiming(1, {duration: 300, easing: Easing.linear}, cb), 53 ), 54 ) 55 }, 56 [circleAnim, checkAnim], 57 ) 58 59 React.useImperativeHandle(ref, () => ({ 60 play, 61 })) 62 63 React.useEffect(() => { 64 if (playOnMount) { 65 play() 66 } 67 }, [play, playOnMount]) 68 69 return ( 70 <Svg 71 fill="none" 72 {...rest} 73 viewBox="0 0 52 52" 74 width={size} 75 height={size} 76 style={style}> 77 <AnimatedCircle 78 animatedProps={circleAnimatedProps} 79 cx="26" 80 cy="26" 81 r="24" 82 fill="none" 83 stroke={fill} 84 strokeWidth={4} 85 strokeDasharray={166} 86 /> 87 <AnimatedPath 88 animatedProps={checkAnimatedProps} 89 stroke={fill} 90 d={PATH} 91 strokeWidth={4} 92 strokeDasharray={48} 93 /> 94 </Svg> 95 ) 96})