react-native-ai-animations 0.0.0-stage → 0.8.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.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -2
  3. package/lib/module/brand/index.js +4 -0
  4. package/lib/module/brand/index.js.map +1 -0
  5. package/lib/module/brand/spinning-mark.js +96 -0
  6. package/lib/module/brand/spinning-mark.js.map +1 -0
  7. package/lib/module/chat/effort-bar.js +853 -0
  8. package/lib/module/chat/effort-bar.js.map +1 -0
  9. package/lib/module/chat/index.js +8 -0
  10. package/lib/module/chat/index.js.map +1 -0
  11. package/lib/module/chat/question-card.js +720 -0
  12. package/lib/module/chat/question-card.js.map +1 -0
  13. package/lib/module/chat/reasoning.js +38 -0
  14. package/lib/module/chat/reasoning.js.map +1 -0
  15. package/lib/module/chat/status-row.js +140 -0
  16. package/lib/module/chat/status-row.js.map +1 -0
  17. package/lib/module/chat/thinking-block.js +255 -0
  18. package/lib/module/chat/thinking-block.js.map +1 -0
  19. package/lib/module/index.js +5 -0
  20. package/lib/module/index.js.map +1 -0
  21. package/lib/module/internal/color.js +15 -0
  22. package/lib/module/internal/color.js.map +1 -0
  23. package/lib/module/internal/use-elapsed.js +20 -0
  24. package/lib/module/internal/use-elapsed.js.map +1 -0
  25. package/lib/module/package.json +1 -0
  26. package/lib/module/skia/dot-orb.js +256 -0
  27. package/lib/module/skia/dot-orb.js.map +1 -0
  28. package/lib/module/skia/index.js +8 -0
  29. package/lib/module/skia/index.js.map +1 -0
  30. package/lib/module/skia/liquid-orb.js +303 -0
  31. package/lib/module/skia/liquid-orb.js.map +1 -0
  32. package/lib/module/skia/matrix-orb.js +272 -0
  33. package/lib/module/skia/matrix-orb.js.map +1 -0
  34. package/lib/module/skia/media-generating.js +524 -0
  35. package/lib/module/skia/media-generating.js.map +1 -0
  36. package/lib/module/skia/voice-wave.js +278 -0
  37. package/lib/module/skia/voice-wave.js.map +1 -0
  38. package/lib/module/text/index.js +6 -0
  39. package/lib/module/text/index.js.map +1 -0
  40. package/lib/module/text/shimmer-text.js +122 -0
  41. package/lib/module/text/shimmer-text.js.map +1 -0
  42. package/lib/module/text/spoken-text.js +85 -0
  43. package/lib/module/text/spoken-text.js.map +1 -0
  44. package/lib/module/text/streaming-text.js +135 -0
  45. package/lib/module/text/streaming-text.js.map +1 -0
  46. package/lib/module/theme/index.js +5 -0
  47. package/lib/module/theme/index.js.map +1 -0
  48. package/lib/module/theme/palette.js +45 -0
  49. package/lib/module/theme/palette.js.map +1 -0
  50. package/lib/module/theme/provider.js +65 -0
  51. package/lib/module/theme/provider.js.map +1 -0
  52. package/lib/typescript/package.json +1 -0
  53. package/lib/typescript/src/brand/index.d.ts +2 -0
  54. package/lib/typescript/src/brand/index.d.ts.map +1 -0
  55. package/lib/typescript/src/brand/spinning-mark.d.ts +21 -0
  56. package/lib/typescript/src/brand/spinning-mark.d.ts.map +1 -0
  57. package/lib/typescript/src/chat/effort-bar.d.ts +42 -0
  58. package/lib/typescript/src/chat/effort-bar.d.ts.map +1 -0
  59. package/lib/typescript/src/chat/index.d.ts +6 -0
  60. package/lib/typescript/src/chat/index.d.ts.map +1 -0
  61. package/lib/typescript/src/chat/question-card.d.ts +73 -0
  62. package/lib/typescript/src/chat/question-card.d.ts.map +1 -0
  63. package/lib/typescript/src/chat/reasoning.d.ts +20 -0
  64. package/lib/typescript/src/chat/reasoning.d.ts.map +1 -0
  65. package/lib/typescript/src/chat/status-row.d.ts +20 -0
  66. package/lib/typescript/src/chat/status-row.d.ts.map +1 -0
  67. package/lib/typescript/src/chat/thinking-block.d.ts +35 -0
  68. package/lib/typescript/src/chat/thinking-block.d.ts.map +1 -0
  69. package/lib/typescript/src/index.d.ts +3 -0
  70. package/lib/typescript/src/index.d.ts.map +1 -0
  71. package/lib/typescript/src/internal/color.d.ts +2 -0
  72. package/lib/typescript/src/internal/color.d.ts.map +1 -0
  73. package/lib/typescript/src/internal/use-elapsed.d.ts +3 -0
  74. package/lib/typescript/src/internal/use-elapsed.d.ts.map +1 -0
  75. package/lib/typescript/src/skia/dot-orb.d.ts +16 -0
  76. package/lib/typescript/src/skia/dot-orb.d.ts.map +1 -0
  77. package/lib/typescript/src/skia/index.d.ts +6 -0
  78. package/lib/typescript/src/skia/index.d.ts.map +1 -0
  79. package/lib/typescript/src/skia/liquid-orb.d.ts +20 -0
  80. package/lib/typescript/src/skia/liquid-orb.d.ts.map +1 -0
  81. package/lib/typescript/src/skia/matrix-orb.d.ts +12 -0
  82. package/lib/typescript/src/skia/matrix-orb.d.ts.map +1 -0
  83. package/lib/typescript/src/skia/media-generating.d.ts +59 -0
  84. package/lib/typescript/src/skia/media-generating.d.ts.map +1 -0
  85. package/lib/typescript/src/skia/voice-wave.d.ts +17 -0
  86. package/lib/typescript/src/skia/voice-wave.d.ts.map +1 -0
  87. package/lib/typescript/src/text/index.d.ts +4 -0
  88. package/lib/typescript/src/text/index.d.ts.map +1 -0
  89. package/lib/typescript/src/text/shimmer-text.d.ts +13 -0
  90. package/lib/typescript/src/text/shimmer-text.d.ts.map +1 -0
  91. package/lib/typescript/src/text/spoken-text.d.ts +15 -0
  92. package/lib/typescript/src/text/spoken-text.d.ts.map +1 -0
  93. package/lib/typescript/src/text/streaming-text.d.ts +16 -0
  94. package/lib/typescript/src/text/streaming-text.d.ts.map +1 -0
  95. package/lib/typescript/src/theme/index.d.ts +3 -0
  96. package/lib/typescript/src/theme/index.d.ts.map +1 -0
  97. package/lib/typescript/src/theme/palette.d.ts +33 -0
  98. package/lib/typescript/src/theme/palette.d.ts.map +1 -0
  99. package/lib/typescript/src/theme/provider.d.ts +13 -0
  100. package/lib/typescript/src/theme/provider.d.ts.map +1 -0
  101. package/package.json +133 -4
  102. package/src/brand/index.ts +5 -0
  103. package/src/brand/spinning-mark.tsx +118 -0
  104. package/src/chat/effort-bar.tsx +748 -0
  105. package/src/chat/index.ts +45 -0
  106. package/src/chat/question-card.tsx +649 -0
  107. package/src/chat/reasoning.ts +30 -0
  108. package/src/chat/status-row.tsx +127 -0
  109. package/src/chat/thinking-block.tsx +250 -0
  110. package/src/index.ts +2 -0
  111. package/src/internal/color.ts +18 -0
  112. package/src/internal/use-elapsed.ts +21 -0
  113. package/src/skia/dot-orb.tsx +248 -0
  114. package/src/skia/index.ts +34 -0
  115. package/src/skia/liquid-orb.tsx +274 -0
  116. package/src/skia/matrix-orb.tsx +337 -0
  117. package/src/skia/media-generating.tsx +389 -0
  118. package/src/skia/voice-wave.tsx +215 -0
  119. package/src/text/index.ts +3 -0
  120. package/src/text/shimmer-text.tsx +140 -0
  121. package/src/text/spoken-text.tsx +82 -0
  122. package/src/text/streaming-text.tsx +144 -0
  123. package/src/theme/index.ts +11 -0
  124. package/src/theme/palette.ts +62 -0
  125. package/src/theme/provider.tsx +54 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ahmet Kar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,227 @@
1
- # Temporary Holding Version
1
+ # React Native AI Animations
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![npm](https://img.shields.io/npm/v/react-native-ai-animations)](https://www.npmjs.com/package/react-native-ai-animations)
4
+ [![license](https://img.shields.io/npm/l/react-native-ai-animations)](LICENSE)
5
+
6
+ Animated React Native and Expo components for AI chat apps: streaming text,
7
+ shimmer loading text, thinking and status indicators, voice orbs and
8
+ waveforms, image and video generation loaders, question cards and reasoning
9
+ effort bars. Built on Reanimated and Skia, themeable, and reduce motion aware.
10
+
11
+ **Docs and live demos:** [nami-motion-web.vercel.app](https://nami-motion-web.vercel.app/)
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npx expo install react-native-ai-animations react-native-reanimated react-native-worklets
17
+ ```
18
+
19
+ The orbs, waveforms and media loaders in `react-native-ai-animations/skia` also need Skia:
20
+
21
+ ```bash
22
+ npx expo install @shopify/react-native-skia
23
+ ```
24
+
25
+ | Peer | Version |
26
+ | --- | --- |
27
+ | `react` | 19.2 or newer |
28
+ | `react-native` | 0.83 or newer |
29
+ | `react-native-reanimated` | 4.2 or newer |
30
+ | `react-native-worklets` | 0.7 or newer |
31
+ | `@shopify/react-native-skia` | 2.4 or newer, optional |
32
+
33
+ > Formerly published as `nami-motion`. Replace `nami-motion` with
34
+ > `react-native-ai-animations` in your imports.
35
+
36
+ ## Components
37
+
38
+ Every component and style is shown in motion, with copyable code and agent
39
+ prompts, on the [website](https://nami-motion-web.vercel.app/).
40
+
41
+ | Component | Entry | What it does |
42
+ | --- | --- | --- |
43
+ | Shimmer Text | `/text` | A light band sweeping across text while a response is being generated. |
44
+ | Streaming Text | `/text` | Words of a streaming answer fade and rise in, with a blinking caret. |
45
+ | Spoken Text | `/text` | Highlights the word being spoken and dims the words already read aloud, for voice replies. |
46
+ | Spinning Mark | `/brand` | Spins any icon you pass (your logo) with optional breathing and entrance. |
47
+ | Status Row | `/chat` | Pulsing icon, shimmering label and elapsed timer for agent status. |
48
+ | Thinking Block | `/chat` | "Thought for Ns" header that springs open into a step timeline. |
49
+ | Question Card | `/chat` | Paged questions with numbered options and a custom answer, as a card or a sheet. |
50
+ | Effort Bar | `/chat` | Reasoning effort control wired to `reasoning.effort` (low, medium, high) in four styles: bars, track, segmented and slider. |
51
+ | Media Generating | `/skia` | One loading state for image and video generation in six variants: blobs, matrix, orbit, scan, constellation and helix. |
52
+ | Dot Orb | `/skia` | The dot sphere behind the media variants, also usable on its own. |
53
+ | Matrix Orb | `/skia` | Dot matrix orb with idle, listening and thinking states and per state colors. |
54
+ | Liquid Orb | `/skia` | Voice orb in metal, water, iridescent or ring material that reacts to idle, listening, thinking and speaking and a live level. |
55
+ | Voice Wave | `/skia` | Live microphone waveform in four styles: lines, bars, dots and pulse. |
56
+
57
+ Entries are subpaths of `react-native-ai-animations`. The root export holds
58
+ `/theme` and `/text`; nothing that needs Skia is imported from the root.
59
+
60
+ Every style is also its own component with the same props minus `variant`:
61
+
62
+ - `VoiceWaveLines`, `VoiceWaveBars`, `VoiceWaveDots`, `VoiceWavePulse`
63
+ - `EffortBars`, `EffortTrack`, `EffortSegmented`, `EffortSlider`
64
+ - `MediaGeneratingBlobs`, `MediaGeneratingMatrix`, `MediaGeneratingOrbit`,
65
+ `MediaGeneratingScan`, `MediaGeneratingConstellation`, `MediaGeneratingHelix`
66
+ - `QuestionSheet`
67
+
68
+ ## Usage
69
+
70
+ ### Shimmer Text
71
+
72
+ ```tsx
73
+ import { ShimmerText } from "react-native-ai-animations/text";
74
+
75
+ <ShimmerText text="Generating a response" activeColor={colors.text} mutedColor={colors.textTertiary} />;
76
+ ```
77
+
78
+ ### Streaming Text, Status Row, Thinking Block
79
+
80
+ ```tsx
81
+ import { StreamingText } from "react-native-ai-animations/text";
82
+ import { StatusRow, ThinkingBlock } from "react-native-ai-animations/chat";
83
+
84
+ <StatusRow label="Searching the web" icon={<Logo />} startedAt={startedAt} />;
85
+ <ThinkingBlock thinking={thinking} startedAt={startedAt} steps={steps} />;
86
+ <StreamingText text={answer} streaming={streaming} textStyle={{ fontFamily: "Inter" }} />;
87
+ ```
88
+
89
+ ### Spinning Mark
90
+
91
+ ```tsx
92
+ import { SpinningMark } from "react-native-ai-animations/brand";
93
+
94
+ <SpinningMark size={160} duration={3600} breathe entrance>
95
+ <Image source={require("./logo.png")} style={{ width: 160, height: 160 }} />
96
+ </SpinningMark>;
97
+ ```
98
+
99
+ ### Question Card
100
+
101
+ ```tsx
102
+ import { QuestionCard } from "react-native-ai-animations/chat";
103
+
104
+ <QuestionCard questions={questions} variant="sheet" onSubmit={(answers) => send(answers)} />;
105
+ ```
106
+
107
+ `QuestionCard` and `QuestionSheet` take a `ref` with `select(index)`,
108
+ `goTo(page)` and `submit()`, so a demo, a voice flow or a test can drive the
109
+ questions without touches.
110
+
111
+ ### Effort Bar
112
+
113
+ `REASONING_EFFORTS` matches the `reasoning.effort` values OpenRouter and most
114
+ reasoning APIs take (`low`, `medium`, `high`), with each level's share of
115
+ `max_tokens`. `reasoningRequest(effort)` builds the request fields.
116
+
117
+ ```tsx
118
+ import { EffortBar, REASONING_EFFORTS, reasoningRequest } from "react-native-ai-animations/chat";
119
+
120
+ <EffortBar levels={REASONING_EFFORTS} value={index} onChange={(i, level) => setEffort(level.value)} accessibilityLabel="Reasoning" />;
121
+ <EffortBar levels={REASONING_EFFORTS} value={index} onChange={(i) => setIndex(i)} variant="segmented" />;
122
+ <EffortBar levels={REASONING_EFFORTS} value={index} onChange={(i) => setIndex(i)} variant="slider" tabLabel={model.name} fillColors={["#5AA2FF", "#2F7BF5"]} levelIcon={(i, color) => <BrainIcon level={i} color={color} />} />;
123
+ <EffortBar levels={REASONING_EFFORTS} value={index} variant="slider" size="compact" />;
124
+
125
+ const body = { model, messages, max_tokens: 16000, ...reasoningRequest(effort) };
126
+ ```
127
+
128
+ | Prop | Does |
129
+ | --- | --- |
130
+ | `variant` | `bars` (default), `track`, `segmented` or `slider` |
131
+ | `size="compact"` | Small inline form for model rows |
132
+ | `fillColors` | Tints the fill of any style |
133
+ | `tabLabel` | Your model name in the slider's tab |
134
+ | `levelIcon` | Replaces every level name with your own icon |
135
+
136
+ EffortBar is only the control: put your own title, level label or description
137
+ around it.
138
+
139
+ ### Media Generating
140
+
141
+ ```tsx
142
+ import { ImageGenerating, MediaGenerating, VideoGenerating } from "react-native-ai-animations/skia";
143
+
144
+ <MediaGenerating variant="constellation" label="Creating image" startedAt={startedAt} />;
145
+ <MediaGenerating variant="scan" chrome="overlay" status="generating" progress={0.42} meta="720p · 6s" aspectRatio={16 / 9} />;
146
+ <ImageGenerating variant="helix" startedAt={startedAt} />;
147
+ <VideoGenerating status="queued" variant="orbit" />;
148
+ ```
149
+
150
+ `ImageGenerating` and `VideoGenerating` are presets of `MediaGenerating`.
151
+
152
+ ### Voice Wave
153
+
154
+ ```tsx
155
+ import { useSharedValue } from "react-native-reanimated";
156
+ import { VoiceWave } from "react-native-ai-animations/skia";
157
+
158
+ const level = useSharedValue(0);
159
+
160
+ <VoiceWave level={level} variant="bars" colors={["#1F8A70", "#88C9F7", "#5FC7B0"]} />;
161
+ ```
162
+
163
+ ### Liquid Orb and Spoken Text
164
+
165
+ `LiquidOrb` comes in `metal`, `water` or `iridescent`, or three glowing loops
166
+ with `ring` (color them with `colors`). `state` switches between `idle`,
167
+ `listening`, `thinking` and `speaking`, and `level` (0 to 1) makes it swell
168
+ while listening or speaking. `SpokenText` highlights the word being read aloud:
169
+ pass the index of the current word as `spoken`.
170
+
171
+ ```tsx
172
+ import { useSharedValue } from "react-native-reanimated";
173
+ import { LiquidOrb } from "react-native-ai-animations/skia";
174
+ import { SpokenText } from "react-native-ai-animations/text";
175
+
176
+ const level = useSharedValue(0);
177
+
178
+ <LiquidOrb material="water" state={isRecording ? "listening" : "idle"} level={level} size={240} />;
179
+ <LiquidOrb material="ring" state="listening" level={level} size={240} colors={["#1F8A70", "#88C9F7", "#5FC7B0"]} />;
180
+ <SpokenText text={reply} spoken={wordIndex} textStyle={{ fontFamily: "Inter", fontSize: 20, lineHeight: 28 }} />;
181
+ ```
182
+
183
+ ## Theming
184
+
185
+ Components use the built-in Moodstone palette until you wrap your app in
186
+ `MotionThemeProvider`. Pass one palette, or a `light` and `dark` pair with a
187
+ `colorScheme`. Components that read the palette also take `colors` to override
188
+ a single instance; Shimmer Text, Voice Wave, Dot Orb and Matrix Orb take their
189
+ colors directly (`activeColor`, `colors`, `color`).
190
+
191
+ ```tsx
192
+ import { useColorScheme } from "react-native";
193
+ import { MotionThemeProvider } from "react-native-ai-animations/theme";
194
+
195
+ <MotionThemeProvider
196
+ colorScheme={useColorScheme() ?? "light"}
197
+ palette={{ light: { accent: "#2F7BF5" }, dark: { accent: "#5AA2FF" } }}
198
+ >
199
+ <App />
200
+ </MotionThemeProvider>;
201
+ ```
202
+
203
+ Palette keys: `background`, `card`, `surface`, `raised`, `text`,
204
+ `textSecondary`, `textTertiary`, `accent`, `accentContrast`, `success`,
205
+ `danger`. Read the active palette in your own components with
206
+ `useMotionPalette()`.
207
+
208
+ ## Customization and accessibility
209
+
210
+ - Icons, fonts, colors and timing are props on every component; nothing is
211
+ tied to a brand or an icon set.
212
+ - When the system's reduce motion setting is on, every component settles to a
213
+ static final state.
214
+
215
+ ## Development
216
+
217
+ ```bash
218
+ npm install
219
+ npm run typecheck
220
+ npm run build
221
+ ```
222
+
223
+ Changes that affect the package need a changeset: `npm run changeset`.
224
+
225
+ ## License
226
+
227
+ [MIT](LICENSE)
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export { SpinningMark } from "./spinning-mark.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["SpinningMark"],"sourceRoot":"../../../src","sources":["brand/index.ts"],"mappings":";;AAAA,SACEA,YAAY,QAGP,oBAAiB","ignoreList":[]}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+
3
+ import { useEffect } from "react";
4
+ import Animated, { cancelAnimation, Easing, useAnimatedStyle, useReducedMotion, useSharedValue, withRepeat, withSequence, withSpring, withTiming } from "react-native-reanimated";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const DEFAULT_DURATION = 3630;
7
+ const DEFAULT_BREATHE = {
8
+ scale: 1.06,
9
+ duration: 1800
10
+ };
11
+ const ENTRANCE_SPRING = {
12
+ damping: 14,
13
+ stiffness: 120,
14
+ mass: 1
15
+ };
16
+ export function SpinningMark({
17
+ children,
18
+ size,
19
+ duration = DEFAULT_DURATION,
20
+ direction = "clockwise",
21
+ easing = Easing.linear,
22
+ breathe = false,
23
+ entrance = false,
24
+ paused = false,
25
+ style,
26
+ accessibilityLabel
27
+ }) {
28
+ const reduceMotion = useReducedMotion();
29
+ const angle = useSharedValue(0);
30
+ const pulse = useSharedValue(1);
31
+ const intro = useSharedValue(entrance && !reduceMotion ? 0 : 1);
32
+ const sign = direction === "clockwise" ? 1 : -1;
33
+ const breatheScale = breathe ? (breathe === true ? undefined : breathe.scale) ?? DEFAULT_BREATHE.scale : 1;
34
+ const breatheDuration = breathe ? (breathe === true ? undefined : breathe.duration) ?? DEFAULT_BREATHE.duration : 0;
35
+ useEffect(() => {
36
+ if (reduceMotion || paused) {
37
+ cancelAnimation(angle);
38
+ return;
39
+ }
40
+ const start = angle.value % 360;
41
+ angle.value = start;
42
+ angle.value = withRepeat(withTiming(start + 360, {
43
+ duration,
44
+ easing
45
+ }), -1, false);
46
+ return () => cancelAnimation(angle);
47
+ }, [angle, duration, easing, paused, reduceMotion]);
48
+ useEffect(() => {
49
+ if (reduceMotion || paused || breatheScale === 1) {
50
+ cancelAnimation(pulse);
51
+ pulse.value = withTiming(1, {
52
+ duration: 200
53
+ });
54
+ return;
55
+ }
56
+ const half = breatheDuration / 2;
57
+ const curve = Easing.inOut(Easing.sin);
58
+ pulse.value = withRepeat(withSequence(withTiming(breatheScale, {
59
+ duration: half,
60
+ easing: curve
61
+ }), withTiming(1, {
62
+ duration: half,
63
+ easing: curve
64
+ })), -1, false);
65
+ return () => cancelAnimation(pulse);
66
+ }, [breatheDuration, breatheScale, paused, pulse, reduceMotion]);
67
+ useEffect(() => {
68
+ if (!entrance || reduceMotion) {
69
+ intro.value = 1;
70
+ return;
71
+ }
72
+ intro.value = withSpring(1, ENTRANCE_SPRING);
73
+ }, [entrance, intro, reduceMotion]);
74
+ const animatedStyle = useAnimatedStyle(() => ({
75
+ opacity: Math.min(1, intro.value * 1.4),
76
+ transform: [{
77
+ rotate: `${sign * angle.value - (1 - intro.value) * 90 * sign}deg`
78
+ }, {
79
+ scale: pulse.value * (0.6 + intro.value * 0.4)
80
+ }]
81
+ }));
82
+ return /*#__PURE__*/_jsx(Animated.View, {
83
+ accessible: !!accessibilityLabel,
84
+ accessibilityRole: accessibilityLabel ? "image" : undefined,
85
+ accessibilityLabel: accessibilityLabel,
86
+ style: [size !== undefined && {
87
+ width: size,
88
+ height: size
89
+ }, {
90
+ alignItems: "center",
91
+ justifyContent: "center"
92
+ }, style, animatedStyle],
93
+ children: children
94
+ });
95
+ }
96
+ //# sourceMappingURL=spinning-mark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useEffect","Animated","cancelAnimation","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withRepeat","withSequence","withSpring","withTiming","jsx","_jsx","DEFAULT_DURATION","DEFAULT_BREATHE","scale","duration","ENTRANCE_SPRING","damping","stiffness","mass","SpinningMark","children","size","direction","easing","linear","breathe","entrance","paused","style","accessibilityLabel","reduceMotion","angle","pulse","intro","sign","breatheScale","undefined","breatheDuration","start","value","half","curve","inOut","sin","animatedStyle","opacity","Math","min","transform","rotate","View","accessible","accessibilityRole","width","height","alignItems","justifyContent"],"sourceRoot":"../../../src","sources":["brand/spinning-mark.tsx"],"mappings":"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","ignoreList":[]}