Skip to content
Native Animation
Flashlight Reveal animation preview

This preview uses fictional demo content. See the props below for the customization options available in this component.

npx nativeanimation add flashlight-reveal
SkiaGlass

Flashlight Reveal

A flashlight search that reveals a reward card, with configurable scene image, offer copy, accent color, and fonts.

$9 for this animation

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

About this animation

A flashlight search that reveals a reward card, with configurable scene image, offer copy, accent color, and fonts.

How it works

  1. The component measures its own container and keeps the full-bleed scene fixed while all positions are derived from its width and height.
  2. A Skia radial gradient creates the soft-edged flashlight. Reanimated shared values drive its center, velocity-responsive radius, warm proximity pulse, and continuous reveal progress.
  3. A pan gesture springs the focus toward the pointer. Remaining within 70 points of the hidden reward for 400 ms triggers discovery.
  4. The same reveal progress expands the clear radius, flies the hidden token toward center, materializes a blurred reward card, and emits a brief warm spark burst.
  5. The forwarded ref exposes deterministic reveal, reset, and guided-tour controls without adding demo-only behavior to the component.

Why this one

Typical flashlight reveals stop at exposing an image. This one turns discovery into a complete product moment: velocity-sensitive light, dwell-based intent, a real hidden object that transforms into an actionable reward, reduced-motion behavior, and a curved autoplay tour designed to land the payoff within three seconds.

Install

npx expo install @shopify/react-native-skia expo-blur expo-image expo-linear-gradient react-native-gesture-handler react-native-reanimated react-native-worklets

Wrap the app with GestureHandlerRootView. Skia web projects must initialize CanvasKit before this component is loaded. Icons: Lucide (ISC).

Usage

import FlashlightReveal from './FlashlightReveal';

export function RewardScreen() {
  return <FlashlightReveal sceneSource={require('./cafe-scene.jpg')} />;
}
const revealRef = useRef<FlashlightRevealRef>(null);

<FlashlightReveal
  ref={revealRef}
  sceneSource={require('./cafe-scene.jpg')}
  title="Find tonight's surprise"
  rewardTitle="A dessert on the house"
  rewardCode="NIGHT-8K2P"
  accentColor="#FB923C"
  focusRadius={132}
  onAddToWallet={saveReward}
/>;

The ref exposes reveal(), reset(), and playTour().

Props

PropTypeDefaultDescription
sceneSourceImageSourcePropTypeRequiredFull-bleed artwork shown beneath the flashlight layer.
titlestring'Find your mystery reward'Search headline.
hintstring'Drag to explore'Gesture hint.
brandNamestring'Ember & Oat'Brand name shown on the hidden token.
rewardLabelstring'Free pastry'Short reward shown on the hidden token.
rewardTitlestring'Free pastry with any drink'Reward headline shown after discovery.
rewardCodestring'EMBER-7Q4K'Reward redemption code.
validThroughstring'Valid through 10/31'Reward expiration copy.
walletLabelstring'Add to wallet'Primary action label.
revealLabelstring'Reveal'Alternative search action label.
resetLabelstring'Try again'Reset action label.
darknessColorstring'rgba(5,4,3,0.94)'Color outside the focus.
accentColorstring'#FB923C'Warm accent used for focus light and reward details.
focusRadiusnumber120Base flashlight radius in points.
fontFamilystringundefinedBody font family.
mediumFontFamilystringundefinedMedium body font family.
titleFontFamilystringundefinedEditorial title font family.
monoFontFamilystringundefinedMonospaced reward code font family.
onReveal() => voidundefinedCalled when the reward finishes being triggered.
onReset() => voidundefinedCalled when the reward is reset.
onAddToWallet() => voidundefinedCalled when the wallet action is pressed.
accessibilityLabelstring'Explore the scene to find a mystery reward'Screen-reader label for the search surface.
styleStyleProp<ViewStyle>undefinedOptional style for the outer container.
testIDstringundefinedTest identifier applied to the outer container.

Compatibility

  • Expo SDK 58
  • React Native 0.88.0
  • Reanimated 4.7.1 and Worklets 0.13.0
  • Skia 2.14.0
  • iOS, Android, and web: supported
  • Expo Go: supported by the SDK 58 bundled modules; use a development build after adding native dependencies to another Expo project

Accessibility

The search surface and all actions have explicit roles and labels, the reveal button provides a touch alternative to dragging, and every action has at least a 44-point hit area. Reduced Motion removes the moving focus and spark choreography, replacing discovery with a short fade to the reward card.

Customization notes

The flashlight follows the gesture. The optional tour keeps its motion and scheduled hold synchronized.