Wheel of fortune spinning animation in React Native (Reanimated)
A prize wheel that feels fair decides the result before the spin, then animates a long ease-out rotation that lands exactly on it.
TL;DR
A wheel of fortune spinning animation in React Native is a wheel drawn with react-native-svg and rotated with Reanimated: you decide the winning segment first, compute the exact angle that lands the pointer on it, and animate a long, decelerating spin to that angle. The detail that separates a real prize wheel from a toy is that the result is chosen before the spin, not decided by where the animation happens to stop. Starting from a free VP0 design and letting Claude Code or Cursor read its source page gets the wheel looking right so you can wire the spin logic on top.
A wheel of fortune spinning animation in React Native is a wheel drawn with react-native-svg and rotated with Reanimated: you decide the winning segment first, compute the exact angle that lands the pointer on it, and animate a long, decelerating spin to that angle. The detail that separates a real prize wheel from a toy is that the result is chosen before the spin, not decided by where the animation happens to stop. The fastest way to get the wheel looking right is to start from a free VP0 design and let Claude Code or Cursor read its source page, then wire the spin logic on top.
A spin wheel is a microinteraction with stakes: it usually hands out a reward, so it has to feel fair, land cleanly on a segment, and never glitch to the wrong prize. The sections below cover drawing the wheel, the spin math, choosing the result, and the mistakes that make a wheel feel rigged or broken.
How do you build a spinning wheel in React Native?
You draw the wheel once as SVG segments, then rotate the whole wheel with a single animated value. Each segment is a pie slice, an SVG Path describing an arc from the center, filled with the segment’s color and labeled with its prize. react-native-svg, with more than 7,000 stars, renders these crisply at any size, and the whole wheel is one group you rotate rather than animating each slice.
The rotation lives in a Reanimated shared value, and an animated style maps it to the wheel’s transform. A pointer sits fixed at the top, so the segment under the pointer when the wheel stops is the result. Both react-native-svg and Reanimated work in Expo with no native code of your own, so the whole wheel runs in a managed project as well as a bare one. Because the wheel is a single rotating group and the pointer is stationary, the math is just an angle, which keeps the whole thing simple and smooth. The reward side of this pattern is covered in the spin-the-wheel daily reward UI.
The spin: rotation, easing, and landing on a segment
The spin is a long rotation that decelerates, so it feels like a real wheel losing momentum. You animate the rotation value to a target that includes several full turns plus the offset that lands the chosen segment under the pointer, using an ease-out curve so it slows naturally at the end.
const rotation = useSharedValue(0);
function spinTo(segmentIndex) {
const segmentAngle = 360 / SEGMENTS;
const target = 360 * 5 + (360 - segmentIndex * segmentAngle - segmentAngle / 2);
rotation.value = withTiming(rotation.value + target, {
duration: 4000,
easing: Easing.out(Easing.cubic),
}, () => {
runOnJS(onResult)(segmentIndex);
});
}
const wheelStyle = useAnimatedStyle(() => ({
transform: [{ rotate: `${rotation.value}deg` }],
}));
The five full turns plus the segment offset give a satisfying long spin that still lands precisely where you intend. The ease-out cubic curve is what makes it feel physical, decelerating into the result rather than stopping abruptly. The callback fires through runOnJS because revealing the prize and updating state happen on the JavaScript thread while the animation runs as a worklet on the UI thread. Adding a + segmentAngle / 2 centers the pointer in the segment rather than on its edge, which avoids the ambiguous look of landing on a divider.
Choose the result first, then animate to it
The most important design decision is that the winning segment is determined before the spin starts, and the animation is told where to land. This is the opposite of letting the wheel spin freely and reading whatever it lands on, and it matters for three reasons: you control the odds, you can enforce business rules like a daily limit or a guaranteed prize, and you avoid floating-point drift leaving the pointer ambiguously on a divider.
So the flow is: pick the segment, on the server or with weighted local logic, then call the spin with that index, then reveal it when the animation settles. A free-spinning wheel that decides its own result looks the same to the user but gives you no control and invites exactly the rounding bugs that land between segments. Weighted odds are easy once the result is chosen up front: a rare jackpot simply gets selected less often, while the animation that lands on it is identical to any other. The gamification layer around this, streaks and rewards, is covered in Duolingo-style gamification assets.
Polishing the feel: pointer, sound, and the reveal
A few touches make the wheel feel finished. The pointer should react on each segment pass, a small tick animation or a haptic as segments cross under it, which sells the sense of a physical wheel slowing down. A short build-up before the spin, the wheel easing into motion rather than jerking, adds to it.
The reveal is the payoff, so let the wheel fully settle before showing the prize, then bring in a confetti burst or a result card with a brief, satisfying animation. Resist firing the reward the instant the value crosses the target; wait for the spring or timing to truly finish so the user sees the wheel stop on their prize first. The same celebratory-reveal pattern shows up in the scratch card UI, where the payoff timing is everything. These details are small individually and together are what make a wheel feel rewarding rather than mechanical.
Making it smooth with AI and a real design
AI builders produce a spinning wheel quickly and get the result logic wrong. Claude Code and Cursor will draw the SVG and animate a rotation, but they tend to let the wheel spin to a random angle and then read the landing segment, which gives you no control over odds and produces off-by-one errors at segment boundaries. They also frequently call the reward function from the worklet without runOnJS, which crashes.
A real design plus the result-first rule fixes most of it. When the wheel layout, segment count, and pointer are already decided, the model draws a correct wheel, and you instruct it to take the winning index as input and compute the target angle to land there. Starting from a free VP0 design gives that structure, since each design has a machine-readable source page Claude Code, Cursor, or Rork read from a pasted link, so the wheel matches a real layout while you own the fairness logic.
Common spinning wheel mistakes
A few mistakes make a wheel feel broken or rigged. Letting the animation decide the result is the first, which loses control of odds and causes landings on segment dividers; choose the result first and animate to it. Calling the reward callback from the worklet without runOnJS is the second, which compiles and crashes on the first spin.
Revealing the prize before the wheel stops is the third, which spoils the payoff and makes the spin feel pointless. A spin that is too short or stops abruptly is the fourth, since a real wheel needs several turns and a decelerating ease-out to feel physical. The fifth is animating each segment instead of rotating the whole wheel as one group, which is more work and more likely to stutter. Keeping the wheel a single rotating group, choosing the result up front, and timing the reveal after the stop are what make it feel fair and satisfying.
When a simpler reward animation is enough
A full spinning wheel is not always the right choice. For a simple daily reward or a single random prize, a card flip, a chest opening, or a brief slot-style reveal communicates the same outcome with far less to build, and there is no segment math to get right. The wheel earns its place when the spin itself is part of the experience and there are several visible prizes the user wants to see go by.
If the reward is binary or there is only one prize, the wheel is overbuilt, and a lighter reveal serves better. Matching the animation to whether the spin is the point, or just the delivery of a reward, keeps you from engineering segment geometry for a coin flip. Decide by how central the wheel is to the moment, and remember that a heavier animation a user sees once a day can wear out faster than a light one, so the simplest reveal that still feels rewarding is often the right call.
Key takeaways: a spin wheel that feels fair
Draw the wheel once as SVG segments and rotate the whole group with a single Reanimated value. Choose the winning segment before the spin and compute the target angle to land it under the pointer, so you control the odds and never stop on a divider. Use several full turns and an ease-out curve for a physical feel, fire the reward through runOnJS only after the wheel fully stops, and time the confetti reveal to the stop. Let an AI builder draw it from a real design, then own the result-first logic yourself. A commissioned gamification feature can cost $5,000 or more, while starting from a free VP0 design gives you the wheel layout for nothing.
You can browse VP0 designs to start your wheel from a real layout rather than a blank component.
Frequently asked questions
How do you make a spinning wheel animation in React Native?
Draw the wheel as SVG segments with react-native-svg, keep the rotation in a Reanimated shared value, and animate it to a target of several full turns plus the offset that lands your chosen segment under a fixed top pointer, using an ease-out curve. Fire the result through runOnJS after the animation settles. Choose the winning segment before the spin so you control the odds. Starting from a free VP0 design gets the wheel layout right so you focus on the spin logic.
How do you make a prize wheel land on a specific segment?
Decide the winning segment first, then compute the target rotation as several full turns plus 360 minus the segment's start angle minus half a segment, which lands the pointer in the center of that segment. Animate the rotation to that exact target rather than to a random angle. This gives you control over the odds and avoids the wheel stopping ambiguously on a divider, which happens when you let the animation pick the result and read where it lands.
Should the animation decide the prize?
No. Choose the prize before the spin and animate the wheel to land on it. Letting a free spin decide the result gives you no control over odds, makes business rules like daily limits or guaranteed prizes impossible, and causes off-by-one errors at segment boundaries from floating-point drift. The user cannot tell the difference visually, but the result-first approach is both fairer to control and more reliable, which is why production prize wheels work that way.
Can VP0 provide a free React Native template for a spin wheel?
Yes. VP0 is a free iOS app design library where every design has a machine-readable source page an AI builder reads from a pasted link, with React Native and SwiftUI variants. You start from the wheel design, with its segments and pointer already laid out, hand its source to Claude Code, Cursor, or Rork, and build the Reanimated spin and result logic on top, rather than drawing the wheel geometry from scratch.
What common errors happen when building a spin wheel?
The frequent ones are letting the animation pick the result so you lose control of odds and land on dividers, calling the reward callback from the worklet without runOnJS so it crashes, revealing the prize before the wheel stops, spinning too briefly to feel physical, and animating each segment instead of rotating the whole wheel as one group. The fixes are choosing the result first, using runOnJS for callbacks, timing the reveal to the stop, and a long ease-out spin on a single rotating group.
Questions from the community
How do you make a spinning wheel animation in React Native?
Draw the wheel as SVG segments with react-native-svg, keep the rotation in a Reanimated shared value, and animate it to a target of several full turns plus the offset that lands your chosen segment under a fixed top pointer, using an ease-out curve. Fire the result through runOnJS after the animation settles. Choose the winning segment before the spin so you control the odds. Starting from a free VP0 design gets the wheel layout right so you focus on the spin logic.
How do you make a prize wheel land on a specific segment?
Decide the winning segment first, then compute the target rotation as several full turns plus 360 minus the segment's start angle minus half a segment, which lands the pointer in the center of that segment. Animate the rotation to that exact target rather than to a random angle. This gives you control over the odds and avoids the wheel stopping ambiguously on a divider, which happens when you let the animation pick the result and read where it lands.
Should the animation decide the prize?
No. Choose the prize before the spin and animate the wheel to land on it. Letting a free spin decide the result gives you no control over odds, makes business rules like daily limits or guaranteed prizes impossible, and causes off-by-one errors at segment boundaries from floating-point drift. The user cannot tell the difference visually, but the result-first approach is both fairer to control and more reliable, which is why production prize wheels work that way.
Can VP0 provide a free React Native template for a spin wheel?
Yes. VP0 is a free iOS app design library where every design has a machine-readable source page an AI builder reads from a pasted link, with React Native and SwiftUI variants. You start from the wheel design, with its segments and pointer already laid out, hand its source to Claude Code, Cursor, or Rork, and build the Reanimated spin and result logic on top, rather than drawing the wheel geometry from scratch.
What common errors happen when building a spin wheel?
The frequent ones are letting the animation pick the result so you lose control of odds and land on dividers, calling the reward callback from the worklet without runOnJS so it crashes, revealing the prize before the wheel stops, spinning too briefly to feel physical, and animating each segment instead of rotating the whole wheel as one group. The fixes are choosing the result first, using runOnJS for callbacks, timing the reveal to the stop, and a long ease-out spin on a single rotating group.
Part of the React Native & Expo: Mobile Frontend Architecture hub. Browse all VP0 topics →
Keep reading
Tinder swipe card animation in React Native with Reanimated
Build a Tinder-style swipe card in React Native with Reanimated and Gesture Handler. Here is the core gesture, the snap logic, and the bugs to avoid.
Voice interrupt animation in React Native: barge-in UI
Build a voice interrupt (barge-in) animation in React Native with Reanimated. Here are the four states, the audio-reactive orb, and the interrupt logic.
WHOOP strain gauge chart in React Native with Skia
Build a WHOOP-style strain gauge in React Native with react-native-skia: a gradient arc, rounded caps, a glow, and a sweep animated to the value with Reanimated.
Live-Stream Tip Shower Animation in React Native
The gift rain is a business mechanic, not decoration: UI-thread particles, value encoded in spectacle, and a shower that only plays once the payment confirms.
Fix Jumping Bottom Sheets in AI Reanimated Code
AI-generated Reanimated bottom sheet jumping or stuttering? Here is why the gesture and animation fight, and how to make it smooth, from a free template.
Fix Reanimated Tinder Swipe Card Memory Leaks in RN
AI-generated Tinder swipe stack leaking memory in React Native? Here is why cards and animation values pile up, and how to clean them so it stays smooth.