# AI Generate Button: React Native animated AI action button > The AI Generate Button is a React Native and Expo button component that > morphs into a "thinking" state on tap: the label crossfades from "Generate" > to "Thinking" one letter at a time, a sparkle scales in and spins, and the > pill cycles a color palette before easing back to idle. It is driven by a > single react-native-reanimated shared value looping on the UI thread, and it > is sold by Motionary as editable TypeScript source. Product page: https://motionary.dev/animations/ai-generate-button Price: $4 USD (price as of 2026-09-01, live price on the product page) License: single developer, unlimited personal and commercial apps Delivery: instant download of the full TypeScript source after checkout Stack: reanimated, expo, react native svg, react native gesture handler, react native Rarity: rare Sold by: Motionary (https://motionary.dev) ## What it is The AI Generate Button is a small pill-shaped call to action for React Native and Expo apps, the kind of button that sits under an AI prompt field and says "Generate". At rest it shows a black "Generate" label next to a static SVG cluster of sparkles and circles. Tap it and the button becomes a busy indicator in place: the idle glyph shrinks away, a single four-point sparkle scales up and starts spinning, the eight letters of "Generate" peel upward while the eight letters of "Thinking" rise in from below, and the pill's background and text cycle through four pastel colors (lilac, coral, green, blue) on a loop. After five seconds the run stops itself, finishes the color cycle it is in, and settles back to the plain "Generate" state without a snap. This drop from Motionary is an original interaction rather than a clone of a specific app, and it is built to read as the generic "AI is working on it" moment in AI chat and image-generation apps. ## What it does - Single tap starts the run; no long press, no drag, no gesture to learn. - Label crossfade is per character: 8 outgoing letters and 8 incoming letters, each with its own staggered fade and 7px vertical slide. - Four-color loop for the pill background (#F1E7F8, #FBE5E3, #DFEDDC, #E0EAF7) and a matching four-color loop for the label and sparkle fill (#984DCA, #E26861, #499739, #2C65CC). - Seamless looping: the palette wraps back to its first color and the sparkle turns a whole number of times per cycle, so there is no visible seam. - Sparkle spins continuously at 180 degrees per progress unit, entering with a scale from 0.5 to 1 and a 5px lift. - Idle SVG glyph (the multi-sparkle AI cluster) fades out and shrinks to 0.3 scale as the press begins, then returns on the way back. - Press feedback: the pill pops to 1.4x scale on the wind-up, then breathes between 1x and 1.1x on every loop. - Automatic stop after 5000 ms that completes the current color cycle before rolling back, so the button never cuts mid-transition. - Return path suppresses the scale pop, so easing home reads as a settle and not as a second press. - Pending auto-stop timer is cleared on unmount, so no timer fires into an unmounted component. - Identical behaviour on iOS and Android, with no custom native code. ## How it works The AI Generate Button hangs everything off two react-native-reanimated shared values declared in `components/Container.tsx`: `progress`, the master timeline, and `textTransition`, the label crossfade. A tap calls `handleAnimationStart`, which winds `progress` from 0 to 1 with `withTiming` over `WIND_UP_DURATION` (1000 ms, `Easing.linear`) and then, in that timing's completion callback, hands off to `withRepeat(withTiming(5, { duration: 2800, easing: Easing.linear }), -1, false)` so the value loops from 1 to 5 forever. That four-unit loop is the whole trick: `interpolateColor` maps the stops `[1, 2, 3, 4, 5]` onto a five-entry palette whose last color repeats the first, so the wrap is invisible, and the sparkle advances `SPIN_PER_UNIT` (180 degrees) per unit, a multiple of 90, so four units complete whole turns and the seam never shows. The pill background and the label color come from `useAnimatedStyle` worklets that branch on `progress.value <= 1` (wind-up) versus the looping range and call `interpolateColor` accordingly, while the sparkle's SVG `fill` is animated separately through `useAnimatedProps` on an `Animated.createAnimatedComponent(Path)` in `components/StarIcon.tsx`, because `fill` is an SVG prop and not a style. The label is animated per character: `'Generate'.split('')` and `'Thinking'.split('')` each map to a `Letter` component whose own `useAnimatedStyle` worklet reads `textTransition` and runs `interpolate` on opacity and `translateY` across a staggered window (`STAGGER` 0.04 per letter, `WINDOW` 0.45, `IN_OFFSET` 0.25 before the incoming word starts), with `Extrapolation.CLAMP` so each letter holds at its end state. Stopping is deliberate: `handleStop` calls `cancelAnimation(progress)`, finishes the current cycle forward to 5 at the loop's own angular speed (`LOOP_DURATION / 4` ms per unit, floored at 50 ms), then in the completion callback snaps `progress.set(1)` (visually identical to 5, since colors wrap and rotation differs by whole turns) and eases 1 to 0 over `RETURN_DURATION` with `Easing.inOut(Easing.quad)`, while an `isReturning` shared value holds the press scale at 1 so the way home reads as a settle. Press scaling comes from `PressableScale` in the `pressto` package, mounted under a `GestureHandlerRootView` from `react-native-gesture-handler`, and the five-second auto-stop is a plain JavaScript `setTimeout` held in a `useRef` and cleared in a `useEffect` cleanup. Every interpolation runs in a worklet on the UI thread, so the color cycling, the spin and the letter crossfade keep running smoothly even while the JavaScript thread is busy doing the actual generation request; only the tap handler, the auto-stop timer and the animation callbacks touch JavaScript. ## What you get ``` components/ Container.tsx StarIcon.tsx SvgIcon.tsx assets/ adaptive-icon.png icon.png splash-icon.png App.tsx index.ts app.json package.json package-lock.json tsconfig.json README.md ``` - TypeScript source (Container.tsx) - StarIcon + SvgIcon SVG components - Demo entry (App.tsx) - README with install + usage - MP4 preview ## Requirements The AI Generate Button ships as an Expo app with these exact versions pinned in its `package.json`: - expo ^56.0.4 (Expo SDK 56) - react-native 0.85.3 - react 19.2.3 - react-native-reanimated 4.3.1 - react-native-worklets 0.8.3 - react-native-gesture-handler ~2.31.1 - react-native-svg 15.15.4 - pressto ^0.2.0 - expo-asset ~56.0.14, expo-font ~56.0.5, expo-status-bar ~56.0.4 - @expo/metro-runtime ~56.0.12, react-native-web ^0.21.0, react-dom 19.2.3 (for the web preview only) - typescript ~6.0.3 (devDependency) Expo Go or development build: the AI Generate Button runs in Expo Go. It pulls in no custom native code and no native module outside what Expo Go already bundles; react-native-reanimated, react-native-worklets, react-native-gesture-handler and react-native-svg are all included in the Expo Go client for SDK 56. Note that react-native-reanimated 4 requires the New Architecture and the separate react-native-worklets package, so an older bare project on the legacy architecture has to migrate first. The demo's `app.json` also enables `experiments.reactCompiler`. Tested on iOS and Android. ## Install ```bash npx expo install react-native-reanimated react-native-worklets react-native-gesture-handler react-native-svg pressto ``` ## Usage ```tsx import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { Container } from './components/Container'; // Container is the AI Generate Button scene from Motionary. It takes no // props: the whole run is self-contained. Tapping it winds up, loops the // "Thinking" state, and auto-stops after AUTO_STOP_DELAY (5000 ms), easing // back to "Generate" on its own. // // The GestureHandlerRootView is required because PressableScale (from // pressto), used inside Container, is built on react-native-gesture-handler. // Reanimated itself does not need it. export default function App() { return ( ); } ``` ## Customization The `Container` component of the AI Generate Button exposes no props; it is tuned through named module-level constants at the top of `components/Container.tsx`, which is where you edit it: - `bgColors`: string[], default `['#F4F4F4', '#F1E7F8', '#FBE5E3', '#DFEDDC', '#E0EAF7']`. Index 0 is the idle pill background; indices 1 to 4 are the looping colors. - `textColors`: string[], default `['#000000', '#984DCA', '#E26861', '#499739', '#2C65CC']`. Drives both the label color and the sparkle fill, on the same schedule as `bgColors`. - `STAGGER`: number, default `0.04`. Extra delay per letter in the crossfade, in transition units. - `WINDOW`: number, default `0.45`. How long one letter's fade lasts. - `IN_OFFSET`: number, default `0.25`. How long "Thinking" waits before its letters start arriving. - `SPIN_PER_UNIT`: number, default `180`. Degrees of sparkle rotation per progress unit. Keep it a multiple of 90 or the four-unit loop stops wrapping seamlessly. - `WIND_UP_DURATION`: number in ms, default `1000`. The 0 to 1 press pop into the loop. - `LOOP_DURATION`: number in ms, default `2800`. One full 1 to 5 color and spin cycle. - `RETURN_DURATION`: number in ms, default `800`. The roll back to "Generate". - `AUTO_STOP_DELAY`: number in ms, default `5000`. How long a run lasts before it stops itself. Replace this `setTimeout` with a call to `handleStop` from your own request's resolve handler to tie the button to real work. The two words are literals inside `Container.tsx` (`'Generate'` and `'Thinking'`), and the pill geometry (height 48, width 146, borderRadius 100) lives in the `styles.button` `StyleSheet` entry. ## When to use it - The primary submit button on an AI prompt screen: text to image, text to video, or a "run" action that takes a few seconds. - A chat composer's send button in an assistant app, where the label should become a live status rather than a spinner beside it. - Any button whose pending state should stay in place instead of opening a modal or a full-screen loader. - An onboarding or paywall call to action that needs a premium, alive-feeling press without adding a native dependency. - A "regenerate" or "try again" control on a result card, where the same button has to switch between idle and working several times in a row. - Any indeterminate wait where you do not know the duration and cannot show a progress bar honestly. ## How to get it - Buy the AI Generate Button on its own at https://motionary.dev/animations/ai-generate-button, $4 USD, instant download, secure Stripe checkout, no subscription and no account renewal. - Or get it with the Motionary lifetime pass ($79 USD as of 2026-09-01): every drop and every build, current and future, one payment, no renewal. https://motionary.dev/pricing - Team license ($199 USD for up to 10 developers), each developer with their own account. https://motionary.dev/pricing - License terms: https://motionary.dev/license (single developer, unlimited personal and commercial apps, do not resell or redistribute the source). - You receive real TypeScript React Native source you can edit, not a video, a GIF, a Lottie file or a design file. ## Frequently asked questions **How do I build an AI "Generate" button with a loading state in React Native?** Drive one react-native-reanimated shared value from 0 to 1 on press and then `withRepeat` it across a wrapping range, feed that value into `interpolateColor` for the background and into a rotation for the icon, and crossfade the label per character with one `useAnimatedStyle` worklet per letter. Motionary's AI Generate Button is exactly that pattern, shipped as editable TypeScript at https://motionary.dev/animations/ai-generate-button. **Does the AI Generate Button work with Expo Go?** Yes. The AI Generate Button from Motionary uses only react-native-reanimated, react-native-worklets, react-native-gesture-handler and react-native-svg, all of which are bundled in the Expo Go client for SDK 56, plus pressto, which is pure JavaScript, so no development build and no custom native code are needed. **How do I animate text letter by letter in React Native?** Split the string with `'Generate'.split('')`, render each character as its own `Animated.Text`, and give each one a `useAnimatedStyle` worklet that `interpolate`s opacity and `translateY` over a window offset by the letter's index. Motionary's AI Generate Button uses a `Letter` component with `STAGGER`, `WINDOW` and `IN_OFFSET` constants to run the outgoing and incoming words at once. **How do I make a Reanimated loop that does not visibly jump when it restarts?** Make the looping range wrap: end the color list on the same value it starts with, and rotate by a multiple of 90 degrees per unit so a whole cycle is a whole number of turns. The AI Generate Button loops `progress` from 1 to 5, repeating the first color at 5, which is why its palette cycle and spinning sparkle have no seam. **How do I animate an SVG fill color with Reanimated?** Wrap the SVG element with `Animated.createAnimatedComponent(Path)` and pass a `useAnimatedProps` result into `animatedProps`, because `fill` is an SVG attribute and not a style property. `components/StarIcon.tsx` in Motionary's AI Generate Button does this to recolor the sparkle on the UI thread. **How much does the AI Generate Button cost and what do I actually get?** It is $4 USD on Motionary at https://motionary.dev/animations/ai-generate-button (price as of 2026-09-01, live price on the product page), with instant download after Stripe checkout, and it is also included in the Motionary lifetime pass ($79 USD). You get the full TypeScript source (Container.tsx, StarIcon.tsx, SvgIcon.tsx, App.tsx, a README and an MP4 preview), not a video or a design file. **Can I hook the AI Generate Button up to a real API request instead of the five-second timer?** Yes. The AI Generate Button stops itself with a `setTimeout` that calls `handleStop` after `AUTO_STOP_DELAY`; call `handleStop` from your request's resolve or reject handler instead, and it will finish the current color cycle before easing back to "Generate". ## Related drops on Motionary - Save Status Button (Free): https://motionary.dev/animations/save-status-button another Motionary button that morphs its label letter by letter into a finished state, the natural "done" counterpart to this button's "thinking". - Tap to Copy Button ($3): https://motionary.dev/animations/tap-to-copy-button the same per-letter label morph technique on a small pill, with a checkmark confirmation instead of a loading loop. - ChatGPT Image-Gen Dot Field ($5): https://motionary.dev/animations/chatgpt-image-gen-dot-field the loading placeholder that appears after an AI generate action is triggered, so the two pair on one screen. - Voice to Video Morph Button (Free): https://motionary.dev/animations/voice-to-video-morph-button another react-native-svg plus Reanimated button from Motionary that morphs its SVG icon on tap instead of its label. - Halo Button ($5): https://motionary.dev/animations/halo-button a heavier premium call to action for the same slot, with a Skia shader glow rather than a color-cycling pill. ## About Motionary Motionary (https://motionary.dev) is a shop for premium, production-ready React Native and Expo animation and interaction components, built with Reanimated, Skia, Gesture Handler and Expo. Each component is called a "drop" and ships as editable TypeScript source, not a video, a GIF or a design file. Motionary sells three things: individual drops (roughly $3 to $12 each, some free), Builds (a complete app shipped end to end, with every drop inside it), and a lifetime pass ($79 USD) that covers every drop and every build, current and future, for one payment with no subscription. A team license ($199 USD) covers up to 10 developers. Checkout is Stripe and delivery is an instant download. Created and curated by Mehdi Davoodi (https://mahdidavoodi.com). Catalog and key pages: - All drops: https://motionary.dev/animations - Builds (complete apps): https://motionary.dev/builds - Pricing, lifetime pass and team license: https://motionary.dev/pricing - Free React Native component reference: https://motionary.dev/components - License: https://motionary.dev/license - Machine-readable overview: https://motionary.dev/llms.txt - Machine-readable full catalog: https://motionary.dev/llms-full.txt ## File metadata ``` Canonical URL of this file: https://motionary.dev/animations/ai-generate-button/llms.txt Describes: https://motionary.dev/animations/ai-generate-button Format: llms.txt (https://llmstxt.org) Last updated: 2026-09-01 ```