Coin Reward
Drag-to-spin coin toss with a Skia scratch card reveal.
Drag-to-spin coin toss
Velocity and translation both feed into flip triggering; a light tap or slow drag just settles back without launching a flip.
Skia-powered scratch reveal
GPU-rendered erase-as-you-scratch overlay over a real Canvas, with grid-based coverage tracking that auto-completes once enough of the card is scratched clear.
Two-moment callback API
onFlipComplete fires the instant the coin lands, onRevealComplete fires once the reward is scratched clear; wire analytics and reward-unlock logic to each separately.
Fork-and-edit reward content
RevealContent ships as a clearly-marked placeholder; swap in your own cashback, coupon, or prize UI directly rather than fighting a config API.
Installation
Copy the command directly into your project.
Install the needed dependencies
Use in your app
Built to match the preview exactly — for the complete implementation, check the repo on GitHub.
import { GestureHandlerRootView } from "react-native-gesture-handler";
import FlipReveal from "../../components/coin-reward/components/FlipReveal";
export default function Screen() {
return (
<GestureHandlerRootView>
<FlipReveal
onFlipComplete={(face) => console.log('flip complete', face)}
onRevealComplete={(face) => console.log('reward revealed', face)}
/>
</GestureHandlerRootView>
)
}API
<FlipReveal>
The batteries-included flow — coin toss into scratch card, wired together with correctly-derived timing.
| Prop | Type | Default | Description |
|---|---|---|---|
| onFlipComplete | (face: CoinFace) => void | — | Called when the coin lands, before the scratch card appears. |
| onRevealComplete | (face: CoinFace) => void | — | Called once the scratch card is fully scratched and the reward is revealed. |
<CoinFlip>
| Prop | Type | Default | Description |
|---|---|---|---|
| onResult | (face: CoinFace) => void | — | Called when the coin finishes settling after a flip. |
<ScratchCard>
| Prop | Type | Default | Description |
|---|---|---|---|
| face | CoinFace | null | — | Which face's reveal content to render underneath the scratch layer. |
| visible | boolean | — | Controls open/close. Animates in on true, slides out on false. |
| onDismiss | () => void | — | Called when the user taps outside the card to dismiss it. |
| onFullyRevealed | () => void | — | Called once the scratch coverage threshold is crossed and the overlay finishes fading out. |
<Coin>
| Prop | Type | Default | Description |
|---|---|---|---|
| face | CoinFace | — | Which face to render. |
| source | ImageSourcePropType | bundled artwork | Override the artwork for this face. Tails artwork should stay forward-facing — CoinFlip applies the 180° mirror via rotateY, so a pre-mirrored image renders backwards. |
| style | StyleProp<ViewStyle> | — | Style override for the coin container. |
Customizing Reward Content
RevealContent renders whatever sits under the scratch layer and is meant to be edited directly rather than configured through props — swap HeadsReveal / TailsReveal in components/RevealContent.tsx for your own cashback, coupon, or prize UI.
Types
type CoinFace = 'heads' | 'tails';