@codeimplants/ui-kit 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/icons/animated/errors/AnimatedClientError.js +21 -9
- package/dist/components/icons/animated/errors/AnimatedCrash.js +47 -25
- package/dist/components/icons/animated/errors/AnimatedInvalidData.js +23 -13
- package/dist/components/icons/animated/maintenance/AnimatedAlert.js +54 -15
- package/dist/components/icons/animated/maintenance/AnimatedEmergency.js +30 -14
- package/dist/components/icons/animated/network/AnimatedTimeout.js +47 -15
- package/dist/components/icons/animated/permissions/AnimatedPermission.js +21 -10
- package/dist/components/icons/animated/permissions/AnimatedPermissionDenied.js +35 -17
- package/package.json +2 -2
- package/src/components/icons/animated/errors/AnimatedClientError.tsx +24 -21
- package/src/components/icons/animated/errors/AnimatedCrash.tsx +52 -68
- package/src/components/icons/animated/errors/AnimatedInvalidData.tsx +28 -42
- package/src/components/icons/animated/maintenance/AnimatedAlert.tsx +63 -33
- package/src/components/icons/animated/maintenance/AnimatedEmergency.tsx +36 -35
- package/src/components/icons/animated/network/AnimatedTimeout.tsx +52 -30
- package/src/components/icons/animated/permissions/AnimatedPermission.tsx +24 -22
- package/src/components/icons/animated/permissions/AnimatedPermissionDenied.tsx +41 -43
- package/src/types/svg.d.ts +20 -0
- package/src/types/reanimated.d.ts +0 -38
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
2
|
-
import Animated,
|
|
3
|
-
|
|
4
|
-
useAnimatedProps,
|
|
5
|
-
withRepeat,
|
|
6
|
-
withSequence,
|
|
7
|
-
withTiming,
|
|
8
|
-
Easing,
|
|
9
|
-
} from 'react-native-reanimated';
|
|
10
|
-
import Svg, { Path, Circle, G } from 'react-native-svg';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { Animated, Easing } from 'react-native';
|
|
3
|
+
import Svg, { Path, Circle } from 'react-native-svg';
|
|
11
4
|
|
|
12
5
|
const AnimatedPath = Animated.createAnimatedComponent(Path);
|
|
13
|
-
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
|
14
6
|
|
|
15
7
|
interface AnimatedCrashProps {
|
|
16
8
|
size?: number;
|
|
@@ -25,88 +17,80 @@ export const AnimatedCrash: React.FC<AnimatedCrashProps> = ({
|
|
|
25
17
|
size = 64,
|
|
26
18
|
color = '#EF4444',
|
|
27
19
|
}) => {
|
|
28
|
-
const scatter1 =
|
|
29
|
-
const scatter2 =
|
|
30
|
-
const scatter3 =
|
|
31
|
-
const opacity = useSharedValue(1);
|
|
20
|
+
const scatter1 = useRef(new Animated.Value(0)).current;
|
|
21
|
+
const scatter2 = useRef(new Animated.Value(0)).current;
|
|
22
|
+
const scatter3 = useRef(new Animated.Value(0)).current;
|
|
32
23
|
|
|
33
24
|
useEffect(() => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
25
|
+
const createAnimation = (value: Animated.Value, durationOut: number, durationIn: number) => {
|
|
26
|
+
return Animated.loop(
|
|
27
|
+
Animated.sequence([
|
|
28
|
+
Animated.timing(value, {
|
|
29
|
+
toValue: 1,
|
|
30
|
+
duration: durationOut,
|
|
31
|
+
easing: Easing.out(Easing.cubic),
|
|
32
|
+
useNativeDriver: true,
|
|
33
|
+
}),
|
|
34
|
+
Animated.timing(value, {
|
|
35
|
+
toValue: 0,
|
|
36
|
+
duration: durationIn,
|
|
37
|
+
easing: Easing.in(Easing.cubic),
|
|
38
|
+
useNativeDriver: true,
|
|
39
|
+
}),
|
|
40
|
+
])
|
|
41
|
+
);
|
|
42
|
+
};
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
),
|
|
48
|
-
-1,
|
|
49
|
-
false
|
|
50
|
-
);
|
|
44
|
+
createAnimation(scatter1, 1200, 800).start();
|
|
45
|
+
createAnimation(scatter2, 1300, 700).start();
|
|
46
|
+
createAnimation(scatter3, 1100, 900).start();
|
|
47
|
+
}, [scatter1, scatter2, scatter3]);
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
);
|
|
49
|
+
const style1 = {
|
|
50
|
+
transform: [
|
|
51
|
+
{ translateX: scatter1.interpolate({ inputRange: [0, 1], outputRange: [0, -8] }) },
|
|
52
|
+
{ translateY: scatter1.interpolate({ inputRange: [0, 1], outputRange: [0, -8] }) },
|
|
53
|
+
],
|
|
54
|
+
opacity: scatter1.interpolate({ inputRange: [0, 1], outputRange: [1, 0.5] }),
|
|
55
|
+
};
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
);
|
|
69
|
-
}, []);
|
|
57
|
+
const style2 = {
|
|
58
|
+
transform: [
|
|
59
|
+
{ translateX: scatter2.interpolate({ inputRange: [0, 1], outputRange: [0, 8] }) },
|
|
60
|
+
{ translateY: scatter2.interpolate({ inputRange: [0, 1], outputRange: [0, -6] }) },
|
|
61
|
+
],
|
|
62
|
+
opacity: scatter2.interpolate({ inputRange: [0, 1], outputRange: [1, 0.5] }),
|
|
63
|
+
};
|
|
70
64
|
|
|
71
|
-
const
|
|
72
|
-
transform:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
opacity: 1 - scatter2.value * 0.5,
|
|
79
|
-
}));
|
|
80
|
-
|
|
81
|
-
const animatedProps3 = useAnimatedProps(() => ({
|
|
82
|
-
transform: `translate(${scatter3.value * -6}, ${scatter3.value * 8})`,
|
|
83
|
-
opacity: 1 - scatter3.value * 0.5,
|
|
84
|
-
}));
|
|
65
|
+
const style3 = {
|
|
66
|
+
transform: [
|
|
67
|
+
{ translateX: scatter3.interpolate({ inputRange: [0, 1], outputRange: [0, -6] }) },
|
|
68
|
+
{ translateY: scatter3.interpolate({ inputRange: [0, 1], outputRange: [0, 8] }) },
|
|
69
|
+
],
|
|
70
|
+
opacity: scatter3.interpolate({ inputRange: [0, 1], outputRange: [1, 0.5] }),
|
|
71
|
+
};
|
|
85
72
|
|
|
86
73
|
return (
|
|
87
74
|
<Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
|
|
88
75
|
{/* Piece 1 - Top left */}
|
|
89
76
|
<AnimatedPath
|
|
90
|
-
animatedProps={animatedProps1}
|
|
91
77
|
d="M20 16 L28 20 L24 28 L16 24 Z"
|
|
92
78
|
fill={color}
|
|
93
|
-
|
|
79
|
+
style={style1 as any}
|
|
94
80
|
/>
|
|
95
81
|
|
|
96
82
|
{/* Piece 2 - Top right */}
|
|
97
83
|
<AnimatedPath
|
|
98
|
-
animatedProps={animatedProps2}
|
|
99
84
|
d="M36 20 L44 16 L48 24 L40 28 Z"
|
|
100
85
|
fill={color}
|
|
101
|
-
|
|
86
|
+
style={style2 as any}
|
|
102
87
|
/>
|
|
103
88
|
|
|
104
89
|
{/* Piece 3 - Bottom */}
|
|
105
90
|
<AnimatedPath
|
|
106
|
-
animatedProps={animatedProps3}
|
|
107
91
|
d="M24 36 L40 36 L38 48 L26 48 Z"
|
|
108
92
|
fill={color}
|
|
109
|
-
|
|
93
|
+
style={style3 as any}
|
|
110
94
|
/>
|
|
111
95
|
|
|
112
96
|
{/* Center crack */}
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
2
|
-
import Animated,
|
|
3
|
-
|
|
4
|
-
useAnimatedProps,
|
|
5
|
-
withRepeat,
|
|
6
|
-
withSequence,
|
|
7
|
-
withTiming,
|
|
8
|
-
Easing,
|
|
9
|
-
} from 'react-native-reanimated';
|
|
10
|
-
import Svg, { Path, Rect, G } from 'react-native-svg';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { Animated, Easing } from 'react-native';
|
|
3
|
+
import Svg, { Path, G } from 'react-native-svg';
|
|
11
4
|
|
|
12
5
|
const AnimatedG = Animated.createAnimatedComponent(G);
|
|
13
|
-
const AnimatedPath = Animated.createAnimatedComponent(Path);
|
|
14
6
|
|
|
15
7
|
interface AnimatedInvalidDataProps {
|
|
16
8
|
size?: number;
|
|
@@ -25,39 +17,30 @@ export const AnimatedInvalidData: React.FC<AnimatedInvalidDataProps> = ({
|
|
|
25
17
|
size = 64,
|
|
26
18
|
color = '#EF4444',
|
|
27
19
|
}) => {
|
|
28
|
-
const glitch =
|
|
29
|
-
const opacity =
|
|
20
|
+
const glitch = useRef(new Animated.Value(0)).current;
|
|
21
|
+
const opacity = useRef(new Animated.Value(1)).current;
|
|
30
22
|
|
|
31
23
|
useEffect(() => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
false
|
|
42
|
-
);
|
|
24
|
+
Animated.loop(
|
|
25
|
+
Animated.sequence([
|
|
26
|
+
Animated.timing(glitch, { toValue: 0, duration: 2000, useNativeDriver: true }),
|
|
27
|
+
Animated.timing(glitch, { toValue: 3, duration: 100, easing: Easing.linear, useNativeDriver: true }),
|
|
28
|
+
Animated.timing(glitch, { toValue: 0, duration: 100, useNativeDriver: true }),
|
|
29
|
+
Animated.timing(glitch, { toValue: -2, duration: 100, useNativeDriver: true }),
|
|
30
|
+
Animated.timing(glitch, { toValue: 0, duration: 100, useNativeDriver: true }),
|
|
31
|
+
])
|
|
32
|
+
).start();
|
|
43
33
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
);
|
|
55
|
-
}, []);
|
|
56
|
-
|
|
57
|
-
const animatedProps = useAnimatedProps(() => ({
|
|
58
|
-
transform: `translateX(${glitch.value})`,
|
|
59
|
-
opacity: opacity.value,
|
|
60
|
-
}));
|
|
34
|
+
Animated.loop(
|
|
35
|
+
Animated.sequence([
|
|
36
|
+
Animated.timing(opacity, { toValue: 1, duration: 2000, useNativeDriver: true }),
|
|
37
|
+
Animated.timing(opacity, { toValue: 0.7, duration: 100, useNativeDriver: true }),
|
|
38
|
+
Animated.timing(opacity, { toValue: 1, duration: 100, useNativeDriver: true }),
|
|
39
|
+
Animated.timing(opacity, { toValue: 0.8, duration: 100, useNativeDriver: true }),
|
|
40
|
+
Animated.timing(opacity, { toValue: 1, duration: 100, useNativeDriver: true }),
|
|
41
|
+
])
|
|
42
|
+
).start();
|
|
43
|
+
}, [glitch, opacity]);
|
|
61
44
|
|
|
62
45
|
return (
|
|
63
46
|
<Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
|
|
@@ -79,7 +62,10 @@ export const AnimatedInvalidData: React.FC<AnimatedInvalidDataProps> = ({
|
|
|
79
62
|
|
|
80
63
|
{/* Glitched content lines */}
|
|
81
64
|
<AnimatedG
|
|
82
|
-
|
|
65
|
+
style={{
|
|
66
|
+
transform: [{ translateX: glitch }],
|
|
67
|
+
opacity: opacity,
|
|
68
|
+
} as any}
|
|
83
69
|
>
|
|
84
70
|
<Path
|
|
85
71
|
d="M22 24 L42 24"
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
2
|
-
import Animated,
|
|
3
|
-
|
|
4
|
-
useAnimatedProps,
|
|
5
|
-
withRepeat,
|
|
6
|
-
withTiming,
|
|
7
|
-
Easing,
|
|
8
|
-
} from 'react-native-reanimated';
|
|
9
|
-
import Svg, { Path, Circle, G } from 'react-native-svg';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { Animated, Easing } from 'react-native';
|
|
3
|
+
import Svg, { Path, Circle } from 'react-native-svg';
|
|
10
4
|
|
|
11
5
|
const AnimatedPath = Animated.createAnimatedComponent(Path);
|
|
12
6
|
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
|
@@ -24,66 +18,102 @@ export const AnimatedAlert: React.FC<AnimatedAlertProps> = ({
|
|
|
24
18
|
size = 64,
|
|
25
19
|
color = '#F59E0B',
|
|
26
20
|
}) => {
|
|
27
|
-
const rotation =
|
|
28
|
-
const ringPulse =
|
|
21
|
+
const rotation = useRef(new Animated.Value(0)).current;
|
|
22
|
+
const ringPulse = useRef(new Animated.Value(0)).current;
|
|
29
23
|
|
|
30
24
|
useEffect(() => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
Animated.loop(
|
|
26
|
+
Animated.sequence([
|
|
27
|
+
Animated.timing(rotation, {
|
|
28
|
+
toValue: 1,
|
|
29
|
+
duration: 150,
|
|
30
|
+
easing: Easing.inOut(Easing.ease),
|
|
31
|
+
useNativeDriver: true,
|
|
32
|
+
}),
|
|
33
|
+
Animated.timing(rotation, {
|
|
34
|
+
toValue: -1,
|
|
35
|
+
duration: 150,
|
|
36
|
+
easing: Easing.inOut(Easing.ease),
|
|
37
|
+
useNativeDriver: true,
|
|
38
|
+
}),
|
|
39
|
+
])
|
|
40
|
+
).start();
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
Animated.loop(
|
|
43
|
+
Animated.timing(ringPulse, {
|
|
44
|
+
toValue: 1,
|
|
45
|
+
duration: 1000,
|
|
46
|
+
easing: Easing.out(Easing.ease),
|
|
47
|
+
useNativeDriver: true,
|
|
48
|
+
})
|
|
49
|
+
).start();
|
|
50
|
+
}, [rotation, ringPulse]);
|
|
43
51
|
|
|
44
|
-
const
|
|
45
|
-
transform:
|
|
46
|
-
|
|
52
|
+
const bellStyle = {
|
|
53
|
+
transform: [
|
|
54
|
+
{ translateX: 32 },
|
|
55
|
+
{ translateY: 24 },
|
|
56
|
+
{ rotate: rotation.interpolate({
|
|
57
|
+
inputRange: [-1, 1],
|
|
58
|
+
outputRange: ['-10deg', '10deg'],
|
|
59
|
+
}) },
|
|
60
|
+
{ translateX: -32 },
|
|
61
|
+
{ translateY: -24 },
|
|
62
|
+
],
|
|
63
|
+
};
|
|
47
64
|
|
|
48
|
-
const
|
|
49
|
-
opacity:
|
|
50
|
-
|
|
51
|
-
|
|
65
|
+
const ringStyle = {
|
|
66
|
+
opacity: ringPulse.interpolate({
|
|
67
|
+
inputRange: [0, 1],
|
|
68
|
+
outputRange: [1, 0],
|
|
69
|
+
}),
|
|
70
|
+
transform: [
|
|
71
|
+
{ translateX: 32 },
|
|
72
|
+
{ translateY: 28 },
|
|
73
|
+
{ scale: ringPulse.interpolate({
|
|
74
|
+
inputRange: [0, 1],
|
|
75
|
+
outputRange: [0.8, 1.3],
|
|
76
|
+
}) },
|
|
77
|
+
{ translateX: -32 },
|
|
78
|
+
{ translateY: -28 },
|
|
79
|
+
],
|
|
80
|
+
};
|
|
52
81
|
|
|
53
82
|
return (
|
|
54
83
|
<Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
|
|
55
84
|
{/* Ring pulse effect */}
|
|
56
85
|
<AnimatedCircle
|
|
57
|
-
animatedProps={ringProps}
|
|
58
86
|
cx="32"
|
|
59
87
|
cy="28"
|
|
88
|
+
r="28"
|
|
60
89
|
stroke={color}
|
|
61
90
|
strokeWidth="2"
|
|
62
91
|
fill="none"
|
|
92
|
+
style={ringStyle as any}
|
|
63
93
|
/>
|
|
64
94
|
|
|
65
95
|
{/* Bell body */}
|
|
66
96
|
<AnimatedPath
|
|
67
|
-
animatedProps={bellProps}
|
|
68
97
|
d="M20 28 C20 20, 26 14, 32 14 C38 14, 44 20, 44 28 L44 36 C44 38, 46 40, 48 40 L16 40 C18 40, 20 38, 20 36 Z"
|
|
69
98
|
fill={color}
|
|
70
99
|
opacity={0.9}
|
|
100
|
+
style={bellStyle as any}
|
|
71
101
|
/>
|
|
72
102
|
|
|
73
103
|
{/* Bell clapper */}
|
|
74
104
|
<AnimatedPath
|
|
75
|
-
animatedProps={bellProps}
|
|
76
105
|
d="M32 40 L32 44"
|
|
77
106
|
stroke={color}
|
|
78
107
|
strokeWidth="2"
|
|
79
108
|
strokeLinecap="round"
|
|
109
|
+
style={bellStyle as any}
|
|
80
110
|
/>
|
|
81
111
|
<AnimatedCircle
|
|
82
|
-
animatedProps={bellProps}
|
|
83
112
|
cx="32"
|
|
84
113
|
cy="46"
|
|
85
114
|
r="2"
|
|
86
115
|
fill={color}
|
|
116
|
+
style={bellStyle as any}
|
|
87
117
|
/>
|
|
88
118
|
|
|
89
119
|
{/* Bell top */}
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
2
|
-
import Animated,
|
|
3
|
-
|
|
4
|
-
useAnimatedProps,
|
|
5
|
-
withRepeat,
|
|
6
|
-
withSequence,
|
|
7
|
-
withTiming,
|
|
8
|
-
Easing,
|
|
9
|
-
} from 'react-native-reanimated';
|
|
10
|
-
import Svg, { Path, Circle, G } from 'react-native-svg';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { Animated, Easing } from 'react-native';
|
|
3
|
+
import Svg, { Path, G } from 'react-native-svg';
|
|
11
4
|
|
|
12
5
|
const AnimatedG = Animated.createAnimatedComponent(G);
|
|
13
6
|
const AnimatedPath = Animated.createAnimatedComponent(Path);
|
|
@@ -25,39 +18,45 @@ export const AnimatedEmergency: React.FC<AnimatedEmergencyProps> = ({
|
|
|
25
18
|
size = 64,
|
|
26
19
|
color = '#DC2626',
|
|
27
20
|
}) => {
|
|
28
|
-
const flash =
|
|
29
|
-
const rotate =
|
|
21
|
+
const flash = useRef(new Animated.Value(0)).current;
|
|
22
|
+
const rotate = useRef(new Animated.Value(0)).current;
|
|
30
23
|
|
|
31
24
|
useEffect(() => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
false
|
|
39
|
-
);
|
|
25
|
+
Animated.loop(
|
|
26
|
+
Animated.sequence([
|
|
27
|
+
Animated.timing(flash, { toValue: 1, duration: 300, useNativeDriver: true }),
|
|
28
|
+
Animated.timing(flash, { toValue: 0, duration: 300, useNativeDriver: true }),
|
|
29
|
+
])
|
|
30
|
+
).start();
|
|
40
31
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
Animated.loop(
|
|
33
|
+
Animated.timing(rotate, {
|
|
34
|
+
toValue: 1,
|
|
35
|
+
duration: 2000,
|
|
36
|
+
easing: Easing.linear,
|
|
37
|
+
useNativeDriver: true,
|
|
38
|
+
})
|
|
39
|
+
).start();
|
|
40
|
+
}, [flash, rotate]);
|
|
47
41
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
42
|
+
const rotateStyle = {
|
|
43
|
+
transform: [
|
|
44
|
+
{ translateX: 32 },
|
|
45
|
+
{ translateY: 24 },
|
|
46
|
+
{ rotate: rotate.interpolate({
|
|
47
|
+
inputRange: [0, 1],
|
|
48
|
+
outputRange: ['0deg', '360deg'],
|
|
49
|
+
}) },
|
|
50
|
+
{ translateX: -32 },
|
|
51
|
+
{ translateY: -24 },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
55
54
|
|
|
56
55
|
return (
|
|
57
56
|
<Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
|
|
58
57
|
{/* Flash rays */}
|
|
59
58
|
<AnimatedG
|
|
60
|
-
|
|
59
|
+
style={rotateStyle as any}
|
|
61
60
|
>
|
|
62
61
|
<Path
|
|
63
62
|
d="M32 8 L32 16 M48 16 L42 22 M54 32 L46 32 M48 48 L42 42 M32 56 L32 48 M16 48 L22 42 M10 32 L18 32 M16 16 L22 22"
|
|
@@ -77,9 +76,11 @@ export const AnimatedEmergency: React.FC<AnimatedEmergencyProps> = ({
|
|
|
77
76
|
|
|
78
77
|
{/* Siren top (light) */}
|
|
79
78
|
<AnimatedPath
|
|
80
|
-
animatedProps={flashProps}
|
|
81
79
|
d="M26 24 L32 16 L38 24 Z"
|
|
82
80
|
fill={color}
|
|
81
|
+
style={{
|
|
82
|
+
opacity: flash,
|
|
83
|
+
} as any}
|
|
83
84
|
/>
|
|
84
85
|
|
|
85
86
|
{/* Siren base */}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
2
|
-
import Animated,
|
|
3
|
-
useSharedValue,
|
|
4
|
-
useAnimatedProps,
|
|
5
|
-
withRepeat,
|
|
6
|
-
withTiming,
|
|
7
|
-
Easing,
|
|
8
|
-
} from 'react-native-reanimated';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { Animated, Easing } from 'react-native';
|
|
9
3
|
import Svg, { Circle, Path } from 'react-native-svg';
|
|
10
4
|
|
|
11
5
|
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
|
@@ -24,31 +18,59 @@ export const AnimatedTimeout: React.FC<AnimatedTimeoutProps> = ({
|
|
|
24
18
|
size = 64,
|
|
25
19
|
color = '#F59E0B',
|
|
26
20
|
}) => {
|
|
27
|
-
const rotation =
|
|
28
|
-
const pulse =
|
|
21
|
+
const rotation = useRef(new Animated.Value(0)).current;
|
|
22
|
+
const pulse = useRef(new Animated.Value(1)).current;
|
|
29
23
|
|
|
30
24
|
useEffect(() => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
Animated.loop(
|
|
26
|
+
Animated.timing(rotation, {
|
|
27
|
+
toValue: 1,
|
|
28
|
+
duration: 2000,
|
|
29
|
+
easing: Easing.linear,
|
|
30
|
+
useNativeDriver: true,
|
|
31
|
+
})
|
|
32
|
+
).start();
|
|
36
33
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
Animated.loop(
|
|
35
|
+
Animated.sequence([
|
|
36
|
+
Animated.timing(pulse, {
|
|
37
|
+
toValue: 1.2,
|
|
38
|
+
duration: 800,
|
|
39
|
+
easing: Easing.inOut(Easing.ease),
|
|
40
|
+
useNativeDriver: true,
|
|
41
|
+
}),
|
|
42
|
+
Animated.timing(pulse, {
|
|
43
|
+
toValue: 1,
|
|
44
|
+
duration: 800,
|
|
45
|
+
easing: Easing.inOut(Easing.ease),
|
|
46
|
+
useNativeDriver: true,
|
|
47
|
+
}),
|
|
48
|
+
])
|
|
49
|
+
).start();
|
|
50
|
+
}, [rotation, pulse]);
|
|
43
51
|
|
|
44
|
-
const
|
|
45
|
-
transform:
|
|
46
|
-
|
|
52
|
+
const clockHandStyle = {
|
|
53
|
+
transform: [
|
|
54
|
+
{ translateX: 32 },
|
|
55
|
+
{ translateY: 32 },
|
|
56
|
+
{ rotate: rotation.interpolate({
|
|
57
|
+
inputRange: [0, 1],
|
|
58
|
+
outputRange: ['0deg', '360deg'],
|
|
59
|
+
}) },
|
|
60
|
+
{ translateX: -32 },
|
|
61
|
+
{ translateY: -32 },
|
|
62
|
+
],
|
|
63
|
+
};
|
|
47
64
|
|
|
48
|
-
const
|
|
49
|
-
transform:
|
|
50
|
-
|
|
51
|
-
|
|
65
|
+
const warningStyle = {
|
|
66
|
+
transform: [
|
|
67
|
+
{ translateX: 48 },
|
|
68
|
+
{ translateY: 16 },
|
|
69
|
+
{ scale: pulse },
|
|
70
|
+
{ translateX: -48 },
|
|
71
|
+
{ translateY: -16 },
|
|
72
|
+
],
|
|
73
|
+
};
|
|
52
74
|
|
|
53
75
|
return (
|
|
54
76
|
<Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
|
|
@@ -73,11 +95,11 @@ export const AnimatedTimeout: React.FC<AnimatedTimeoutProps> = ({
|
|
|
73
95
|
|
|
74
96
|
{/* Clock hands */}
|
|
75
97
|
<AnimatedPath
|
|
76
|
-
animatedProps={clockHandProps}
|
|
77
98
|
d="M32 32 L32 20"
|
|
78
99
|
stroke={color}
|
|
79
100
|
strokeWidth="2.5"
|
|
80
101
|
strokeLinecap="round"
|
|
102
|
+
style={clockHandStyle as any}
|
|
81
103
|
/>
|
|
82
104
|
<Path
|
|
83
105
|
d="M32 32 L38 32"
|
|
@@ -96,11 +118,11 @@ export const AnimatedTimeout: React.FC<AnimatedTimeoutProps> = ({
|
|
|
96
118
|
|
|
97
119
|
{/* Warning indicator */}
|
|
98
120
|
<AnimatedCircle
|
|
99
|
-
animatedProps={warningProps}
|
|
100
121
|
cx="48"
|
|
101
122
|
cy="16"
|
|
102
123
|
r="6"
|
|
103
124
|
fill={color}
|
|
125
|
+
style={warningStyle as any}
|
|
104
126
|
/>
|
|
105
127
|
<Path
|
|
106
128
|
d="M48 13 L48 16 M48 18 L48 18.5"
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
2
|
-
import Animated,
|
|
3
|
-
|
|
4
|
-
useAnimatedProps,
|
|
5
|
-
withRepeat,
|
|
6
|
-
withTiming,
|
|
7
|
-
Easing,
|
|
8
|
-
} from 'react-native-reanimated';
|
|
9
|
-
import Svg, { Path, Circle, G } from 'react-native-svg';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { Animated, Easing } from 'react-native';
|
|
3
|
+
import Svg, { Path, G } from 'react-native-svg';
|
|
10
4
|
|
|
11
5
|
const AnimatedG = Animated.createAnimatedComponent(G);
|
|
12
6
|
|
|
@@ -23,20 +17,26 @@ export const AnimatedPermission: React.FC<AnimatedPermissionProps> = ({
|
|
|
23
17
|
size = 64,
|
|
24
18
|
color = '#3B82F6',
|
|
25
19
|
}) => {
|
|
26
|
-
const scale =
|
|
20
|
+
const scale = useRef(new Animated.Value(1)).current;
|
|
27
21
|
|
|
28
22
|
useEffect(() => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
23
|
+
Animated.loop(
|
|
24
|
+
Animated.sequence([
|
|
25
|
+
Animated.timing(scale, {
|
|
26
|
+
toValue: 1.1,
|
|
27
|
+
duration: 1500,
|
|
28
|
+
easing: Easing.inOut(Easing.ease),
|
|
29
|
+
useNativeDriver: true,
|
|
30
|
+
}),
|
|
31
|
+
Animated.timing(scale, {
|
|
32
|
+
toValue: 1,
|
|
33
|
+
duration: 1500,
|
|
34
|
+
easing: Easing.inOut(Easing.ease),
|
|
35
|
+
useNativeDriver: true,
|
|
36
|
+
}),
|
|
37
|
+
])
|
|
38
|
+
).start();
|
|
39
|
+
}, [scale]);
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
42
|
<Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
|
|
@@ -57,7 +57,9 @@ export const AnimatedPermission: React.FC<AnimatedPermissionProps> = ({
|
|
|
57
57
|
|
|
58
58
|
{/* Checkmark */}
|
|
59
59
|
<AnimatedG
|
|
60
|
-
|
|
60
|
+
style={{
|
|
61
|
+
transform: [{ scale: scale }],
|
|
62
|
+
} as any}
|
|
61
63
|
>
|
|
62
64
|
<Path
|
|
63
65
|
d="M24 30 L30 36 L42 24"
|