scratch_reveal

Pub Version ![Pub Points](https://img.shields.io/pub/points/scratch_reveal?style=flat-square[![Pub Points](https://pub.flutter-io.cn/packages/scratch_reveal/score)color=2E8B57[![Pub Points](https://img.shields.io/pub/points/scratch_reveal?style=flat-square&color=2E8B57&label=pub%20points)](https://pub.flutter-io.cn/packages/scratch_reveal/score)label=pub%20points)](https://pub.flutter-io.cn/packages/scratch_reveal/score) Live Demo Pub Likes CI License

A high-performance, GPU-accelerated scratch card and scratch-to-reveal canvas widget for Flutter with sub-millisecond spatial bitmask area tracking, smooth auto-reveal animations, and customizable foil styles.

scratch_reveal demo


⚑ Why scratch_reveal?

Existing scratch card packages on pub.flutter-io.cn suffer from a fundamental architectural flaw: they calculate scratch coverage by reading raw bitmap pixels out of CPU image buffers on every drag stroke, causing micro-stutters and frame drops.

scratch_reveal solves this with a 2D Spatial Bitmask Grid Engine:

  1. Sub-0.1ms Progress Calculation: Calculates the exact percentage scratched instantly without querying GPU memory or freezing the UI thread.
  2. GPU BlendMode.clear Pipeline: Buttery smooth 120 FPS eraser strokes on high-refresh-rate mobile devices.
  3. Threshold Auto-Reveal & Animations: Smoothly fades/scales out remaining foil once the target threshold (e.g. 60%) is reached.
  4. Rich Styling: Solid colors, multi-stop metallic gradients (silver/gold foil), or custom widget overlays.
  5. Zero Native C++: 100% pure Flutter & Dart across iOS, Android, Web, macOS, Windows, and Linux.

πŸ“¦ Installation

Add scratch_reveal to your pubspec.yaml:

dependencies:
  scratch_reveal: ^1.1.1

Or run:

flutter pub add scratch_reveal

πŸš€ Quick Start

1. Metallic Foil Scratch Card with Auto-Reveal

import 'package:flutter/material.dart';
import 'package:scratch_reveal/scratch_reveal.dart';

class PromoScratchCard extends StatelessWidget {
  const PromoScratchCard({super.key});

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 320,
      height: 180,
      child: ClipRRect(
        borderRadius: BorderRadius.circular(20),
        child: ScratchReveal(
          brushSize: 40.0,
          threshold: 0.65, // Auto-reveals at 65% scratched
          coverGradient: const LinearGradient(
            colors: [Color(0xFFE2E8F0), Color(0xFF94A3B8), Color(0xFF475569)],
          ),
          cover: const Center(
            child: Text('SCRATCH TO REVEAL', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white)),
          ),
          revealedChild: Container(
            color: const Color(0xFFD97706),
            alignment: Alignment.center,
            child: const Text('πŸŽ‰ β‚Ή500 VOUCHER CODE: LUCKY2026', style: TextStyle(color: Colors.white, fontSize: 16)),
          ),
          onThresholdReached: () {
            print('Reward unlocked!');
          },
          onProgressUpdate: (progress) {
            print('Progress: ${(progress * 100).toInt()}%');
          },
        ),
      ),
    );
  }
}

2. Programmatic Reveal & Reset

final scratchKey = GlobalKey<ScratchRevealState>();

// Reset the card back to unscratched:
scratchKey.currentState?.reset();

// Automatically reveal the reward:
scratchKey.currentState?.reveal();

πŸ› οΈ API Reference

ScratchReveal Properties

Property Type Default Description
revealedChild Widget Required The underlying prize or content to be revealed.
cover Widget? null Optional visual widget overlay (e.g. icon + text).
coverColor Color Color(0xFF64748B) Solid color of the scratch foil.
coverGradient Gradient? null Gradient for realistic metallic foil textures.
brushSize double 36.0 Thickness of the eraser stroke in logical pixels.
threshold double 0.60 Fraction in [0.0, 1.0] needed to trigger auto-reveal.
autoReveal bool true Whether to animate remaining foil away at threshold.
revealDuration Duration Duration(milliseconds: 600) Transition animation duration.
onThresholdReached VoidCallback? null Fired once when threshold is met.
onProgressUpdate ValueChanged<double>? null Continuous progress callback [0.0, 1.0].
enableHaptics bool false Triggers subtle tactile haptics while scratching.

πŸ’– Support the Project

If you find this project useful, consider supporting its active maintenance and future development:

Buy Me A Coffee GitHub Sponsors Patreon


πŸ“„ License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Maintained with ❀️ by Govind Tank.

Libraries

scratch_reveal
High-performance GPU-accelerated scratch card and scratch-to-reveal canvas widget for Flutter.