A landscape-first coloring and drawing app for iOS: trace dashed outlines, color 80+ hand-drawn illustrations, and get an accuracy score computed by an on-device image-comparison engine. Published on the App Store.
TODO(anton): screenshot — levels grid with difficulty columns and progress badges TODO(anton): screenshot — drawing canvas mid-stroke with reference preview and accuracy bar TODO(anton): screenshot — results overlay with coverage/precision/color score breakdown TODO(anton): video/gif — pinch-zoom + eyedropper + stroke smoothing in action TODO(anton): screenshot — paywall with weekly trial offer
- Custom canvas engine — raw pointer-event pipeline (no
GestureDetectordrawing): Chaikin-style quadratic bezier stroke smoothing, per-point pressure from Apple Pencil, eraser viaBlendMode.clearover a layered canvas, and hand-rolled two-finger pinch/pan transform math with jitter-free recentering. - Coloring accuracy scoring — the user's strokes are snapshotted and compared against the reference per pixel in a chunk grid: coverage, precision, color accuracy, and an overflow penalty for painting outside the silhouette. Scores feed a live progress bar and a results breakdown.
- Level system — 80+ illustrations across four difficulty tiers, progressive thumbnail precaching, per-level progress persisted as gzip-compressed stroke blobs (resume exactly where you left off).
- Monetization — weekly subscription with a 3-day trial via StoreKit (
in_app_purchase), paywall compliant with App Store guidelines, AppLovin MAX interstitials/rewarded ads with AdMob mediation, premium users go ad-free. - Analytics & experiments — Tenjin (including AppLovin ILRD ad-revenue forwarding), Facebook App Events, and an A/B framework currently testing a "speed coloring" timed mode.
Flutter / Dart · provider · in_app_purchase (StoreKit) · applovin_max · tenjin_plugin · facebook_app_events · shared_preferences · vector_math
Classic layered Flutter layout: lib/presentation (screens + widgets + ChangeNotifier providers) over lib/core/services (scoring, ads, progress, analytics) and lib/data (models, subscription repository). The drawing screen owns a raw Listener-driven canvas; ComparisonService downsamples and scores stroke snapshots against the reference; ProgressService serializes sessions to disk. Native iOS config lives in ios/ with secrets injected at build time (see below).
flutter pub get
# Provide secrets: copy the template and fill in your keys
cp keys.json.example keys.json
# Generates lib/core/config/secrets.dart and ios/Flutter/Secrets.xcconfig
dart tool/inject_secrets.dart
flutter runFor TestFlight / App Store archives, build from Xcode (ios/Runner.xcworkspace → Product → Archive). Detailed internal build and versioning instructions (RU): docs/build-ios.ru.md.
keys.json lives only locally and is gitignored — never commit it. tool/inject_secrets.dart turns it into two generated, gitignored artifacts: lib/core/config/secrets.dart (XOR-obfuscated constants consumed via Secrets.*) and ios/Flutter/Secrets.xcconfig (build variables referenced from Info.plist). To rotate a key: update keys.json, re-run the inject script, rebuild. No source file ever contains a real key.
- App Store: Cozy Coloring — Learn to Draw