Scratchify
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!
Install / Use
/learn @gsrathoreniks/ScratchifyREADME
Scratchify - A Compose Multiplatform Scratch Card SDK
<a href="https://www.producthunt.com/products/scratchify-sdk-mobile-scratch-rewards?embed=true&utm_source=badge-featured&utm_medium=badge&utm_source=badge-scratchify-sdk-mobile-scratch-rewards" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=998237&theme=light&t=1753626002349" alt="Scratchify SDK – Mobile Scratch Rewards - Gamify your app with scratch-to-reveal magic ✨ | Product Hunt" style="width: 100px; height: 22px;" width="100" height="21" /></a>
🚀 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:
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 brushBrushShape.Square- Square brush strokesBrushShape.Star(points: Int = 5)- Star-shaped brushBrushShape.Heart- Heart-shaped brushBrushShape.Diamond- Diamond-shaped brushBrushShape.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 animationFADE- Fade out effectSCALE- Scale down effectSLIDE_UP- Slide up and disappearSLIDE_DOWN- Slide down and disappearSLIDE_LEFT- Slide left and disappearSLIDE_RIGHT- Slide right and disappearBOUNCE- Bouncy scale effectZOOM_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.Transparentfor traditional scratch-off behavior - Use any other color for paint/overlay effects
- Combine with `opac
