Bluesky app fork with some witchin' additions 馃挮
witchsky.app
bluesky
fork
client
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})