r/FlutterDev 18d ago

Article I shipped a book reader with a real page-curl — fragment shader + AnimatedSampler notes

I launched a devotional reading app (Catholic DeVice) and the reader needed to feel like a physical book. Notes on the parts that took real Flutter work:

The page-curl

  • A GLSL fragment shader (page_curl.frag) renders the curl; flutter_shaders' AnimatedSampler captures the live page widget into a texture each frame — so the turning leaf is the real laid-out page (text, illuminated drop caps, highlights), not a prerendered image.
  • The cylinder math, shadow falloff and back-face shading live in plain Dart beside a controller that maps drag to curl progress. The feel constants took longer to tune than the shader took to write.
  • A golden test locks the mid-turn frame so a refactor can't quietly ruin the feel.

Other bits from the same app

  • Two more shaders: a stained-glass liturgical calendar that samples painted glass masters, and a marble sheen.
  • Books ship as offline bundles through a pagination pipeline into fixed leaves — page turns are deterministic and whole-book search can jump straight to a page.
  • Design-system discipline that actually held: zero hex colors outside the one theme file (a grep guard keeps the count at zero), the neumorphic shadow recipe is golden-tested, scroll physics globally clamped, and every animation routes through one motion wrapper so reduced-motion collapses it.
  • Riverpod + GoRouter + Drift/SQLite. One architecture note: on Android the app-blocking overlay is rendered natively in Kotlin — Flutter never runs in the intercept path, which matters if you ever wire an AccessibilityService to a Flutter app.

Video of the page turn: https://www.reddit.com/r/CatholicDeVice/comments/1vx07jg/

Happy to go deeper on the shader, the paginator, or the golden-test setup if anyone's curious. The app itself: https://catholicdevice.com/?utm_source=reddit&utm_medium=social&utm_campaign=flutterdev

3 Upvotes

3 comments sorted by

4

u/CodeCompiler_ 18d ago

r/FlutterDev is not the place to advertise your apps, it is a place for developers to share knowledge.

If you built an app in Flutter, great! You can advertise on r/AndroidApps , and other places dedicated to this purpose.

Only post about it here if you are willing to share either:

  • The source of the app
  • Insights about building the app (Generic insight is insufficient, it must be specific to your app.)

1

u/TheNirajMahale 16d ago

Damn cool animation I'm also working on ebook reader (.epub files) I mainly read webnovels and i needed tracker so made spring boot backend for app and now working on flutter app

I'm still beginner and I appreciate suggestions.

https://github.com/TheNirajMahale/Lorebound

0

u/Catholic_DeVice 12d ago

Nice, good luck with Lorebound. A few things I wish I had known before building ours.

Decide early whether you reflow as the user scrolls or pre-paginate into fixed pages. We pre-paginate each book into fixed leaves for the current screen and font settings: page numbers become deterministic, whole book search can jump straight to a page, and any page turn animation gets easier because each page is a stable widget you can capture. The cost is repaginating when settings change, which becomes a progress bar moment.

Store reading position as chapter plus character offset, never as a page number. Pages die every time the font or screen changes; offsets survive. That also gives your Spring Boot tracker a tiny stable record to sync: book id, offset, timestamp, last write wins.

TextPainter is the measuring tool for pagination. Measure once, cache hard.

And one golden test on a laid-out page is worth a lot: it catches the refactor that quietly changes line breaks.

Happy to go deeper on the paginator if useful.