real_page_flip 2.1.1 copy "real_page_flip: ^2.1.1" to clipboard
real_page_flip: ^2.1.1 copied to clipboard

A high-fidelity 3D-like page flip engine for Flutter. Features physics-based paper fold effects with realistic shadows, sound, and haptic feedback for ultra-smooth performance.

Real Page Flip Engine for Flutter #

pub package tests analysis Sponsor License Live Demo platforms

A production-hardened page flip engine for Flutter. Single-page and double-spread. Physics-based paper fold, adaptive haptics, sound, dark mode. Runs on Android, iOS, Web (CanvasKit + WASM), Windows, macOS, and Linux — all 6 Flutter platforms.

Built for RealBible. Running in Production. #

Real Page Flip is the rendering engine behind two live Google Play apps:

This is not a weekend prototype. It is the engine that thousands of readers use every time they turn a page. Every edge case below was encountered on a real device, reported by a real user, and fixed:

Real-world issue Resolved
iPhone SE haptic motor buzz Fixed
Dark-paper shadow blade artifacts Fixed
Single-page flap splitting into stacked sheets Fixed
Extreme vertical drag causing layer seams Fixed
GPU memory leak from static shader cache Fixed

1,199 tests. 0 analyzer issues. Free (MIT) for any project, commercial or personal.

This engine is different because it has already solved edge cases that only surface after thousands of real-world page turns.

English | 한국어

What Sets This Engine Apart #

  • Real-device verified: Tested on budget iPhone SE and low-end Android devices — every listed bug was reported by an actual user and fixed.
  • 1,199 tests, 0 analyzer issues: Covers gesture arbitration, geometry invariants, memory lifecycle, accessibility, and stress scenarios.
  • Adaptive performance: Three rendering profiles (low/medium/high) automatically scale to device capability.
  • Physics-modeled visuals: Crease shadows, paper curl shading, and dark-paper moonlight tones derived from physical paper behavior.
  • Complete sensory feedback: Continuous haptic waveform pipeline synchronized with speed-varying page-rustle audio.
  • Production architecture: 31 focused source files with documented structure.

Demos #

Live Web Preview #

Try it in your browser →

Drag or tap the pages to feel the physics. Switch between single-page and double-spread mode, tune sensitivity and paper opacity, or toggle haptics (on a real device) — all from the in-app control deck.

Mobile single-page view #

Four slow page turns on a portrait mobile viewport using the high-quality rendering profile.

[Mobile single-page page flip]

16:9 double-spread view #

Four slow spread turns with distinct left- and right-page content, on a 16:9 landscape viewport.

[16:9 double-spread page flip]

Technical Foundation #

Hybrid Snapshot Engine #

During a flip, the renderer works from flattened page textures instead of repainting the full widget tree every frame. Actual frame rate depends on page capture cost, device, and host layout.

Intelligent Memory Windowing #

Retained page state is bounded around the active page window. Whether your book has 10 pages or 10,000, memory footprint stays constant.

Lightweight Geometry Engine #

Curved clips, dynamic shadows, and highlights are calculated with a custom math-based Path Clipping engine — no heavy 3D perspective transforms.

Production-Hardened Layouts #

Internal constraint gate prevents "unbounded height" errors in common Stack, Column, and Scaffold compositions.


Sensory Experience #

  • Sound: High-quality page-rustle audio that varies naturally with gesture speed.
  • Haptics: Perceptual gain pipeline with adaptive quality routing. Continuous waveform texture on premium devices, discrete confirmation on basic motors.

Installation #

flutter pub add real_page_flip

Quick Start #

import 'package:real_page_flip/real_page_flip.dart';

PageFlipWidget(
  itemCount: 10,
  itemBuilder: (context, index) => MyPage(index),
)

Single-page settle policy #

Controls whether the moving back face eases into the destination near the end of a single-page turn. Disable for a stable back face until the page commits:

PageFlipWidget(
  config: const PageFlipConfig(
    enableSinglePageSettleReveal: false,
  ),
  itemCount: 10,
  itemBuilder: (context, index) => MyPage(index),
)

Double-spread mode always maps the physical verso and ignores this setting.

Snapshot refresh and thermal budget #

For long, scrollable, or provider-heavy pages, use dirty-aware refreshing:

final flipController = PageFlipController();

PageFlipWidget(
  controller: flipController,
  contentRevision: documentRevision,
  config: const PageFlipConfig(
    snapshotRefreshPolicy: PageFlipSnapshotRefreshPolicy.whenDirty,
    maxSnapshotPixelRatio: 2.25,
  ),
  itemCount: pages.length,
  itemBuilder: (context, index) => pages[index],
)

flipController.markPageDirty(changedPageIndex);
flipController.markCurrentPageDirty(prewarm: false);

whenDirty observes scrolling and pre-captures after scroll end. Use contentRevision for declarative refresh, or markPageDirty() for one page. maxSnapshotPixelRatio caps only the moving raster texture; settled content remains at native resolution.

Flip Sensitivity #

Independent forward/backward drag thresholds and gesture sensitivity:

PageFlipWidget(
  config: PageFlipConfig(
    cutoffForward: 0.35,
    cutoffPrevious: 0.5,
    sensitivity: 0.5,
  ),
  itemCount: 10,
  itemBuilder: (context, index) => MyPage(index),
)

Double-spread (two-page) mode #

PageFlipWidget(
  spreadMode: PageFlipSpreadMode.doubleSpread,
  itemCount: spreadCount,
  config: PageFlipConfig(
    flapBackStrength: 0.0, // mirrored back text disabled by default
  ),
  itemBuilder: (context, spreadIndex) => MyTwoPageSpread(spreadIndex),
)
Responsibility Detail
itemBuilder Each index renders a full-width spread (left + right pages).
itemCount Number of spreads (e.g. ceil(pageCount / 2)).
Spine reveal Forward reveals the left half of the next spread; backward the right half of the previous.

Dark Mode #

Theme-aware by default. Shadows, highlights, and edge masks adapt automatically based on background luminance. Zero config:

MaterialApp(
  theme: ThemeData.light(),
  darkTheme: ThemeData.dark(),
  themeMode: ThemeMode.system,
  home: Scaffold(
    body: PageFlipWidget(
      itemCount: pages.length,
      itemBuilder: (context, index) => MyPage(index),
    ),
  ),
)

Performance Benchmark #

cd example
flutter run --profile -t lib/performance_benchmark.dart \
  --dart-define=PERFORMANCE_PROFILE=medium \
  --dart-define=FLIPS=80

The benchmark runs 80 consecutive page flips on a real device and reports:

Metric Target
Build time (avg) < 6 ms
Raster time (avg) < 5 ms
P90 frame time < 10 ms
P99 frame time < 12 ms
Max frame time < 18 ms
Jank count (80 flips) 0

Run across low/medium/high profiles to validate your target device tier. The benchmark is designed to catch regressions in snapshot capture, geometry computation, and shader performance before they reach users.

Support the Project #

Real Page Flip is free (MIT) and always will be. Maintaining a production-grade engine — running 1,199 tests, verifying fixes across real devices, and keeping pace with Flutter releases — requires sustained investment.

Sponsor on GitHub →

For companies, sponsorship tiers include having your name or logo listed here.

License #

MIT — free for any project, commercial or personal. See LICENSE.

Built by ChaPDCha

6
likes
0
points
1.44k
downloads

Publisher

verified publishersharebible.org

Weekly Downloads

A high-fidelity 3D-like page flip engine for Flutter. Features physics-based paper fold effects with realistic shadows, sound, and haptic feedback for ultra-smooth performance.

Homepage
Repository (GitHub)
View/report issues

Topics

#page-flip #animation #book #ebook #physics

License

unknown (license)

Dependencies

audioplayers, flutter

More

Packages that depend on real_page_flip