Skip to content

ChaPDCha/flutter_real_page_flip

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

50 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Real Page Flip Engine for Flutter

pub package License Flutter

A professional, high-fidelity 3D-like page flip engine for Flutter. Specifically engineered to deliver ultra-smooth 60/120 FPS performance even on low-end devices through advanced rendering optimizations.

English | ํ•œ๊ตญ์–ด

Demos

1. Full Performance Demo (v1.2+)

Performance Demo

2. Legacy Interaction Demo (Core Physics)

Interaction Demo

Why Real Page Flip? (The Technical Edge)

Most page flip libraries struggle with performance as UI complexity increases. Real Page Flip is built differently:

1. Hybrid Snapshot Engine (GPU Optimization)

Unlike other libraries that attempt to render live widget trees during heavy animations, our engine captures high-resolution snapshots of your pages.

  • The Benefit: During a flip, the GPU only handles a single flattened texture (RawImage) instead of hundreds of nested widgets. This guarantees silky-smooth motion even with extremely complex page layouts.

2. Intelligent Memory Windowing

Whether your book has 10 pages or 10,000, the memory footprint remains constant.

  • The Benefit: We only maintain the current, previous, and next pages in the widget tree. This prevents the "Memory Bloat" common in standard PageView-based implementations.

3. Zero-Overhead Geometry Engine

We avoid heavy 3D perspective transforms that can be jittery on older hardware. Instead, we use a custom math-based Path Clipping engine.

  • The Benefit: Perfectly clean curls, dynamic shadows, and specular highlights with minimal computational overhead.

4. Production-Hardened Layouts (Single Constraint Gate)

Ever had a "Vertical viewport was given unbounded height" error? Not here.

  • The Benefit: Our internal "Constraint Gate" ensures the engine works perfectly inside any parentโ€”be it a Stack, Column, or Scaffoldโ€”without manual size adjustments.

Sensory Experience: Sound and Haptics

What truly sets this engine apart is the immersive sensory feedback:

  • Physical Sound Effects: High-quality rustle sounds that vary naturally with your gesture speed.
  • Tactile Haptics: Feel the friction and the "snap" of the paper through your device's haptic engine.

Installation

Add real_page_flip to your pubspec.yaml:

dependencies:
  real_page_flip: ^1.4.0

Quick Start

import 'package:real_page_flip/real_page_flip.dart';

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

Flip Sensitivity

Control the drag-release threshold for completing page flips in each direction:

PageFlipWidget(
  config: PageFlipConfig(
    // Forward flip completes when drag exceeds 40 % (default 0.4)
    cutoffForward: 0.35,
    // Backward flip threshold (default 0.4)
    cutoffPrevious: 0.5,
    // Overall gesture sensitivity (0.0 = firm, 1.0 = light touch)
    sensitivity: 0.5,
  ),
  itemCount: 10,
  itemBuilder: (context, index) => MyPage(index),
)

Higher values require dragging further across the page to complete a flip. Setting forward/previous independently lets you tune bias (e.g. easier to go forward than backward).

Double-spread (two-page) mode

For books that show left and right pages together:

PageFlipWidget(
  spreadMode: PageFlipSpreadMode.doubleSpread, // or isDoubleSpread: true
  itemCount: spreadCount, // number of spreads, not single pages
  config: PageFlipConfig(
    skipTapAnimation: false, // required to animate spine-band reveal on tap
  ),
  itemBuilder: (context, spreadIndex) => MyTwoPageSpread(spreadIndex),
)

Host contract

Responsibility Detail
itemBuilder Each index renders a full-width spread (left + right pages).
itemCount Number of spreads (e.g. ceil(pageCount / 2)).
Stable builder Use a method or const closureโ€”not a new inline lambda every build, or snapshots reset too often.
Snapshots The engine captures spreadSnapshots[currentIndex ยฑ 1] when includeCurrentSpread is true (flip start, page settle, init).
Spine reveal Forward flip reveals the left half of the next spread; backward reveals the right half of the previous spread.

Use clipSpreadPageHalf from the engine when aligning host layout with flip layers.

Dark Mode Support

The engine is theme-aware by default. With backgroundColor: null (the default since v1.3.0), the flipping page automatically uses the host app's scaffoldBackgroundColor, and shadow/highlight intensities are calculated from the background luminance at paint time.

Zero-config automatic dark mode

MaterialApp(
  theme: ThemeData.light(),
  darkTheme: ThemeData.dark(),
  themeMode: ThemeMode.system,
  home: Scaffold(
    body: PageFlipWidget(
      itemCount: pages.length,
      itemBuilder: (context, index) => MyPage(index),
      // No config needed โ€” dark mode just works
    ),
  ),
)

Custom dark paper color

final isDark = Theme.of(context).brightness == Brightness.dark;

PageFlipWidget(
  config: PageFlipConfig(
    backgroundColor: isDark
        ? const Color(0xFF1A1F3A)  // dark navy
        : const Color(0xFFEEEEEE), // warm paper
  ),
  itemCount: pages.length,
  itemBuilder: (context, index) => MyPage(index),
)

What adapts automatically

Element Light mode Dark mode
Paper back color scaffoldBackgroundColor scaffoldBackgroundColor
Inner shadow strength 35 % 20 % (softer)
Fold highlight 5 % 18 % (stronger for depth)
Edge tap indicator Dark glow Light glow

Note: Page content (text, images, backgrounds) is controlled by your itemBuilder. The engine only manages the flip animation layer.

License

This project uses a Dual License model:

  • Non-commercial: Free for personal/open-source projects.
  • Commercial: Requires a paid license for revenue-generating products. See LICENSE for details.

ํ•œ๊ตญ์–ด (Korean)

Real Page Flip Engine์€ ํ”Œ๋Ÿฌํ„ฐ๋ฅผ ์œ„ํ•œ ๊ณ ์„ฑ๋Šฅ ๋ฌผ๋ฆฌ ๊ธฐ๋ฐ˜ ํŽ˜์ด์ง€ ์ „ํ™˜ ์—”์ง„์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ์ €์‚ฌ์–‘ ๊ธฐ๊ธฐ์—์„œ๋„ ๋Š๊น€ ์—†๋Š” 60/120 FPS ์„ฑ๋Šฅ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋œ ๋…๋ณด์ ์ธ ๋ Œ๋”๋ง ์ตœ์ ํ™” ๊ธฐ์ˆ ์ด ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์ˆ ์  ์ฐจ๋ณ„์  (Professional Edge)

  1. ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ์Šค๋ƒ…์ƒท ์—”์ง„: ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ค‘ ๋ณต์žกํ•œ ์œ„์ ฏ ํŠธ๋ฆฌ๋ฅผ ๋งค ํ”„๋ ˆ์ž„ ๋‹ค์‹œ ๊ทธ๋ฆฌ๋Š” ๋Œ€์‹ , ํŽ˜์ด์ง€๋ฅผ ๊ณ ํ•ด์ƒ๋„ ์ด๋ฏธ์ง€๋กœ ์บก์ฒ˜ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋•๋ถ„์— ์•„๋ฌด๋ฆฌ ๋ณต์žกํ•œ UI๋ผ๋„ GPU ๋ถ€ํ•˜ ์—†์ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.
  2. ์ง€๋Šฅํ˜• ๋ฉ”๋ชจ๋ฆฌ ์œˆ๋„์ž‰: ์ˆ˜๋งŒ ์žฅ์˜ ํŽ˜์ด์ง€๊ฐ€ ์žˆ์–ด๋„ ํ˜„์žฌ์™€ ์•ž๋’ค ํŽ˜์ด์ง€, ๋‹จ 3์žฅ๋งŒ ๋ฉ”๋ชจ๋ฆฌ์— ์œ ์ง€ํ•˜์—ฌ ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๋ฅผ ์›์ฒœ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.
  3. ์ œ๋กœ-์˜ค๋ฒ„ํ—ค๋“œ ์ง€์˜ค๋ฉ”ํŠธ๋ฆฌ: ๋ฌด๊ฑฐ์šด 3D ๋ณ€ํ™˜ ๋Œ€์‹  ์ •๊ตํ•œ ์ˆ˜ํ•™์  ๊ฒฝ๋กœ ํด๋ฆฌํ•‘(Path Clipping)์„ ์‚ฌ์šฉํ•˜์—ฌ ๊นจ๋—ํ•œ ์ข…์ด ํœ˜์–ด์ง๊ณผ ๊ทธ๋ฆผ์ž ํšจ๊ณผ๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
  4. ๊ฒฌ๊ณ ํ•œ ๋ ˆ์ด์•„์›ƒ ์„ค๊ณ„: 'Constraint Gate' ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ์–ด๋–ค ๋ณต์žกํ•œ ์œ„์ ฏ ํŠธ๋ฆฌ ์•ˆ์—์„œ๋„ ๋ ˆ์ด์•„์›ƒ ์—๋Ÿฌ ์—†์ด ์•ˆ์ •์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

Built with by ChaPDCha

About

High-performance, physics-based page flip engine for Flutter. 60/120 FPS optimized for low-end devices with haptic and sound feedback. ๐Ÿ“–โœจ

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors