flutter_scratch_card 2.0.0 copy "flutter_scratch_card: ^2.0.0" to clipboard
flutter_scratch_card: ^2.0.0 copied to clipboard

A production-ready, highly customizable Flutter scratch card SDK with ImageProvider overlays, themes, brushes, haptics, multi-area scratching, persistence, and accessibility.

flutter_scratch_card #

A production-ready, highly customizable Flutter scratch card SDK.

pub package License: MIT

Scratch Card Demo

Features #

  • ImageProvider overlaysNetworkImage, AssetImage, MemoryImage, with loading/error fallback
  • Configurable brushes — size, softness, hardness, spacing, shapes (circle, square, rounded rect, custom)
  • Reveal shapes — rectangle, circle, rounded rectangle, custom path
  • Themes — classic, metallic, golden, premium, neon, minimal (fully overridable)
  • Callbacks — start / scratch / end / progress / milestone / threshold / complete / reset
  • Haptics — throttled light / medium / heavy / selection feedback
  • Optional sounds — adapter API (no audio package required)
  • Completion effects — fade, scale, glow, confetti, shake (no heavy deps)
  • Controller API — reveal, reset (optional animated), pause, resume, progress
  • Multi-area scratching — independent regions with per-area completion
  • Async / multi rewards — first, random, predefined, or host-loaded
  • Accessibility — semantics label/hint + “reveal” action
  • Persistence — pluggable ScratchStateStorage (in-memory built-in)
  • Performance controls — grid resolution, point caps, progress throttling
  • Lottie / GIF celebrations under the scratch layer (optional lottie)

Installation #

dependencies:
  flutter_scratch_card: ^2.0.0
flutter pub get

Basic usage #

ScratchCard(
  overlayImage: const AssetImage('assets/scratch.png'),
  child: const Text('₹100'),
)

Controller #

final controller = ScratchController();

ScratchCard(
  controller: controller,
  onComplete: () {},
  child: reward,
);

controller.reveal();
controller.reset(animated: true);
controller.pause();
controller.resume();
print(controller.progress);
print(controller.isComplete);

Customization #

ScratchCard(
  theme: ScratchCardTheme.premium(),
  brush: ScratchBrush.soft(size: 35),
  revealShape: ScratchRevealShape.circle(),
  overlayImage: const NetworkImage('https://example.com/scratch.png'),
  fallbackOverlayImage: const AssetImage('assets/fallback.png'),
  haptic: const ScratchHapticConfig(
    onScratch: HapticType.light,
    onMilestone: HapticType.medium,
    onComplete: HapticType.heavy,
  ),
  completion: const ScratchCompletionConfig(
    effect: ScratchCompletionEffect.confetti,
  ),
  animation: const ScratchAnimationConfig(
    duration: Duration(milliseconds: 500),
    curve: Curves.easeOut,
  ),
  child: reward,
)

Callbacks #

ScratchCard(
  progressTriggers: const [0.25, 0.5, 0.75],
  onScratchStart: () {},
  onScratch: (offset) {},
  onScratchEnd: () {},
  onProgress: (p) {},
  onMilestone: (m) {},
  onThreshold: () {},
  onComplete: () {},
  onReset: () {},
  child: reward,
)

onComplete fires once until reset(). Auto-reveal and controller.reveal() also trigger it.

Advanced #

Multiple areas #

Areas are laid out in a horizontal row using flex:

ScratchCard(
  areas: [
    ScratchArea(id: 'left', flex: 1, child: Text('A')),
    ScratchArea(id: 'right', flex: 1, child: Text('B')),
  ],
  onAreaComplete: (id) {},
  child: const SizedBox.shrink(),
)

Async reward #

ScratchCard(
  rewardSelection: ScratchRewardSelection.async,
  rewardBuilder: (context) async => Text(await fetchPrize()),
  rewardLoadingBuilder: (_) => const CircularProgressIndicator(),
  rewardErrorBuilder: (context, error, retry) =>
      TextButton(onPressed: retry, child: const Text('Retry')),
  child: const SizedBox.shrink(),
)

Persistence #

ScratchCard(
  stateKey: 'daily_reward_2026_08_21',
  stateStorage: MemoryScratchStateStorage(), // or your SharedPreferences adapter
  child: reward,
)

Implement ScratchStateStorage to persist with SharedPreferences, Hive, etc.

Sound (optional) #

class MyPlayer implements ScratchSoundPlayer {
  @override
  Future<void> playScratch() async { /* audioplayers / just_audio */ }
  @override
  Future<void> playComplete() async {}
  @override
  void dispose() {}
}

ScratchCard(
  sound: ScratchSoundConfig(enabled: true, player: MyPlayer()),
  child: reward,
)

Performance #

  • Grid-based progress (configurable resolution)
  • Soft cap on scratch points
  • Optional progress update throttling
  • RepaintBoundary isolation for overlay vs reward layers
  • Throttled haptics / sounds during drag
performance: ScratchPerformanceConfig.lowEnd(),

Accessibility #

ScratchCard(
  semanticLabel: 'Scratch card containing a reward',
  semanticHint: 'Scratch to reveal your reward',
  child: reward,
)

Semantics also expose a tap/reveal action for users who cannot drag.

API reference #

See the Dart API docs on pub.dev.

Migration (1.x → 2.0) #

See MIGRATION.md.

Breaking highlights:

  • overlayImage is now ImageProvider? (was ui.Image?)
  • Use overlayUiImage for a decoded ui.Image
  • Prefer AssetImage over deprecated overlayImageAsset

License #

MIT — see LICENSE.

5
likes
160
points
499
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A production-ready, highly customizable Flutter scratch card SDK with ImageProvider overlays, themes, brushes, haptics, multi-area scratching, persistence, and accessibility.

Repository (GitHub)
View/report issues

Topics

#scratch-card #ui #animation #rewards #flutter

License

MIT (license)

Dependencies

flutter, lottie

More

Packages that depend on flutter_scratch_card