Skip to content

Scratchify is a lightweight and customizable scratch card SDK built using Jetpack Compose Multiplatform. It enables you to create interactive scratch surfaces where users can scratch off an overlay to reveal hidden content underneath. Ideal for rewards, discounts, surprise reveals, and gamification elements in your app!

License

Notifications You must be signed in to change notification settings

gsrathoreniks/Scratchify

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

18 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Scratchify - A Compose Multiplatform Scratch Card SDK

Scratchify Github: Open Issues Scratchify Github Followers Twitter Follow GitHub License Scratchify SDK โ€“ Mobile Scratch Rewards - Gamify your app with scratch-to-reveal magic โœจ | Product Hunt

Scratchify


๐Ÿš€ Introduction

Scratchify is a powerful and highly customizable scratch card SDK built using Jetpack Compose Multiplatform. It enables you to create engaging interactive scratch surfaces where users can scratch off an overlay to reveal hidden content underneath. Perfect for reward systems, discount reveals, surprise elements, and gamification in your modern apps!

Perfect for:
โœ… Reward reveals & lottery systems
โœ… Discount coupons & promotional codes
โœ… Interactive surprise elements
โœ… Gamification features & mini-games
โœ… Educational apps & learning activities
โœ… User engagement & retention strategies


โœจ Features

๐ŸŽฏ Core Features

โœ”๏ธ Multiplatform support (Android & iOS)
โœ”๏ธ Two-layer scratch surface (Overlay & Revealed Content)
โœ”๏ธ Customizable brush configuration (size, color, opacity)
โœ”๏ธ Auto-reveal after threshold (configurable percentage)
โœ”๏ธ Scratch event callbacks (onScratchStarted, onScratchProgress, onScratchCompleted)

๐Ÿš€ Advanced Features

โœ”๏ธ Instant reveal & reset functionality
โœ”๏ธ Tap-to-scratch detection alongside drag gestures
โœ”๏ธ Configurable grid resolution for performance optimization
โœ”๏ธ Save & restore scratch state for persistent experiences
โœ”๏ธ Cross-platform haptic feedback (iOS & Android)
โœ”๏ธ Animated reveal effects (fade, scale, slide, bounce, zoom)
โœ”๏ธ Custom brush shapes (circle, square, star, heart, diamond, custom paths)
โœ”๏ธ Transparent & colored brush modes (traditional scratch or paint effects)


๐Ÿ“ฆ Implementation

1๏ธโƒฃ Add Dependency

Since Scratchify is a Compose Multiplatform (CMP) library, you should add it to your commonMain source set to use it across both iOS and Android.

Add the dependency in your shared module's build.gradle.kts:

Maven Central

dependencies {
    implementation("io.github.gsrathoreniks:scratchify:<latest_version>")
}

2๏ธโƒฃ Basic Usage

import com.gsrathoreniks.scratchify.api.Scratchify
import com.gsrathoreniks.scratchify.api.ScratchifyController
import com.gsrathoreniks.scratchify.api.config.ScratchifyConfig

@Composable
fun BasicScratchCard() {
    val controller = remember { ScratchifyController() }
    
    Scratchify(
        modifier = Modifier.size(300.dp, 200.dp),
        config = ScratchifyConfig(),
        controller = controller,
        contentToReveal = {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color(0xFFFFD700)),
                contentAlignment = Alignment.Center
            ) {
                Text("๐ŸŽ‰ You Won! ๐ŸŽ‰", style = MaterialTheme.typography.headlineMedium)
            }
        },
        overlayContent = {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color(0xFF8E24AA)),
                contentAlignment = Alignment.Center
            ) {
                Text("Scratch Here!", color = Color.White)
            }
        }
    )
}

3๏ธโƒฃ Advanced Configuration

@Composable
fun AdvancedScratchCard() {
    val controller = remember { 
        ScratchifyController(
            ScratchifyConfig(
                // Core settings
                revealFullAtPercent = 0.6f,
                gridResolution = 100,
                enableTapToScratch = true,
                
                // Brush configuration
                brushConfig = ScratchifyBrushConfig(
                    brushSize = 30.dp,
                    brushColor = Color.Red,
                    opacity = 0.8f,
                    brushShape = BrushShape.Star(points = 5)
                ),
                
                // Haptic feedback
                hapticConfig = ScratchifyHapticConfig(
                    isEnabled = true,
                    onScratchStarted = HapticFeedbackType.LIGHT,
                    onScratchProgress = HapticFeedbackType.LIGHT,
                    onScratchCompleted = HapticFeedbackType.SUCCESS,
                    progressHapticInterval = 0.25f
                ),
                
                // Animation effects
                animationConfig = ScratchifyAnimationConfig(
                    revealAnimationType = RevealAnimationType.BOUNCE,
                    animationDurationMs = 800,
                    enableProgressAnimation = true
                )
            )
        )
    }
    
    // Controller API usage
    Row {
        Button(onClick = { controller.revealInstantly() }) {
            Text("Reveal")
        }
        Button(onClick = { controller.resetScratch() }) {
            Text("Reset")
        }
    }
    
    Scratchify(
        modifier = Modifier.size(300.dp, 200.dp),
        config = controller.config,
        controller = controller,
        contentToReveal = { /* Your content */ },
        overlayContent = { /* Your overlay */ }
    )
}

๐ŸŽจ Configuration Options

Core Configuration (ScratchifyConfig)

Parameter Type Default Description
revealFullAtPercent Float 0.75f Auto-reveal threshold (0.0 to 1.0)
isScratchingEnabled Boolean true Enable/disable scratching
gridResolution Int 150 Grid resolution for performance tuning
enableTapToScratch Boolean true Allow single taps to create scratches

Brush Configuration (ScratchifyBrushConfig)

Parameter Type Default Description
brushSize Dp 4.dp Size of the brush stroke
brushColor Color Color.Cyan Brush color (Color.Transparent for traditional scratch)
opacity Float 1f Brush opacity (0.0 to 1.0)
brushShape BrushShape BrushShape.Circle Shape of the brush stroke

Brush Shapes (BrushShape)

  • BrushShape.Circle - Classic circular brush
  • BrushShape.Square - Square brush strokes
  • BrushShape.Star(points: Int = 5) - Star-shaped brush
  • BrushShape.Heart - Heart-shaped brush
  • BrushShape.Diamond - Diamond-shaped brush
  • BrushShape.Custom(path: Path, size: Dp) - Custom path shapes

Haptic Feedback (ScratchifyHapticConfig)

Parameter Type Default Description
isEnabled Boolean true Enable haptic feedback
onScratchStarted HapticFeedbackType LIGHT Feedback when scratching begins
onScratchProgress HapticFeedbackType NONE Feedback during scratching
onScratchCompleted HapticFeedbackType SUCCESS Feedback when completed
progressHapticInterval Float 0.25f Progress interval for haptic feedback

Animation Effects (ScratchifyAnimationConfig)

Parameter Type Default Description
revealAnimationType RevealAnimationType FADE Type of reveal animation
animationDurationMs Int 500 Animation duration in milliseconds
enableProgressAnimation Boolean true Enable progress animations

Animation Types (RevealAnimationType)

  • NONE - No animation
  • FADE - Fade out effect
  • SCALE - Scale down effect
  • SLIDE_UP - Slide up and disappear
  • SLIDE_DOWN - Slide down and disappear
  • SLIDE_LEFT - Slide left and disappear
  • SLIDE_RIGHT - Slide right and disappear
  • BOUNCE - Bouncy scale effect
  • ZOOM_OUT - Zoom out effect

๐ŸŽฎ Controller API

The ScratchifyController provides programmatic control over the scratch card:

val controller = remember { ScratchifyController() }

// Instant actions
controller.revealInstantly()  // Reveal content immediately
controller.resetScratch()     // Reset to initial state

// State management
val state = controller.saveState()        // Save current scratch state
controller.restoreState(state)            // Restore saved state

// Progress monitoring
val progress = controller.scratchProgress // Current scratch progress (0.0 to 1.0)

๐Ÿ”„ Migration from Previous Versions

Brush Color/Opacity

  • Use Color.Transparent for traditional scratch-off behavior
  • Use any other color for paint/overlay effects
  • Combine with opacity for semi-transparent effects

Performance Optimization

  • Lower gridResolution (75-100) for better performance on complex layouts
  • Higher gridResolution (150-200) for more precise scratch detection

๐ŸŽฏ Example Use Cases

๐ŸŽฒ Lottery & Gaming

Scratchify(
    config = ScratchifyConfig(
        revealFullAtPercent = 0.8f,
        brushConfig = ScratchifyBrushConfig(brushSize = 25.dp),
        hapticConfig = ScratchifyHapticConfig(
            onScratchCompleted = HapticFeedbackType.SUCCESS
        ),
        animationConfig = ScratchifyAnimationConfig(
            revealAnimationType = RevealAnimationType.BOUNCE
        )
    ),
    contentToReveal = { LotteryPrizeContent() },
    overlayContent = { LotteryTicketOverlay() }
)

๐ŸŽจ Creative Paint Mode

Scratchify(
    config = ScratchifyConfig(
        brushConfig = ScratchifyBrushConfig(
            brushSize = 35.dp,
            brushColor = Color.Magenta,
            opacity = 0.7f,
            brushShape = BrushShape.Star(points = 6)
        )
    ),
    contentToReveal = { CanvasBackground() },
    overlayContent = { PaintSurface() }
)

๐Ÿ“ฑ Mobile Engagement

Scratchify(
    config = ScratchifyConfig(
        enableTapToScratch = true,
        gridResolution = 100, // Optimized for mobile
        hapticConfig = ScratchifyHapticConfig(
            progressHapticInterval = 0.3f
        )
    ),
    contentToReveal = { RewardContent() },
    overlayContent = { EngagementOverlay() }
)

๐Ÿ›  Platform Support

Platform Haptic Feedback Performance Status
Android โœ… Full Support โšก Optimized โœ… Stable
iOS โœ… Full Support โšก Optimized โœ… Stable

Platform-Specific Features

Android:

  • Vibrator API integration
  • Pattern-based haptic feedback
  • Performance optimizations for various device types

iOS:

  • UIImpactFeedbackGenerator support
  • UINotificationFeedbackGenerator for success/error
  • Native iOS haptic patterns

๐Ÿ“Š Performance Tips

  1. Grid Resolution: Lower values (75-100) for better performance
  2. Brush Size: Larger brushes require fewer touch points
  3. Haptic Intervals: Increase interval (0.3f+) to reduce battery usage
  4. Animation Duration: Shorter animations (300-500ms) feel more responsive

๐ŸŽฎ Advanced Features Guide

State Persistence

// Save current scratch progress
val scratchState = controller.saveState()
// Later restore the exact same state
controller.restoreState(scratchState)

Custom Brush Shapes

val customPath = Path().apply {
    // Define your custom shape
    moveTo(-10f, -10f)
    lineTo(10f, -10f)
    lineTo(0f, 10f)
    close()
}

ScratchifyBrushConfig(
    brushShape = BrushShape.Custom(customPath, 30.dp)
)

Performance Monitoring

val controller = remember { ScratchifyController() }

// Monitor progress in real-time
LaunchedEffect(controller.scratchProgress) {
    println("Scratch progress: ${(controller.scratchProgress * 100).toInt()}%")
}

๐Ÿค Contributing

We welcome contributions from the community! ๐Ÿš€

๐Ÿ›  Submitting Issues & Feature Requests

๐Ÿ’ก Development Setup

  1. Clone the repository
  2. Open in Android Studio
  3. Run the sample app to see all features in action

We appreciate your help in improving Scratchify! ๐ŸŽ‰


๐Ÿ“œ License

This project is licensed under the MIT License.

๐Ÿ“„ Read the full license: MIT License


๐Ÿ™ Acknowledgments

  • Built with โค๏ธ using Jetpack Compose Multiplatform
  • Haptic feedback implementation inspired by platform best practices
  • Animation system leveraging Compose's powerful animation APIs
  • Performance optimizations based on real-world usage patterns

Made with โค๏ธ for the Compose Multiplatform community

About

Scratchify is a lightweight and customizable scratch card SDK built using Jetpack Compose Multiplatform. It enables you to create interactive scratch surfaces where users can scratch off an overlay to reveal hidden content underneath. Ideal for rewards, discounts, surprise reveals, and gamification elements in your app!

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages