phantasm_read 0.0.3 copy "phantasm_read: ^0.0.3" to clipboard
phantasm_read: ^0.0.3 copied to clipboard

Cross-platform Flutter comic and novel reader package.

[phantasm_read]

phantasm_read #

Cross-platform Flutter comic / novel / PDF reader package (0.0.3).

中文文档

Install #

dependencies:
  phantasm_read: ^0.0.3

License: MIT

import 'package:phantasm_read/phantasm_read.dart';

Quick start #

ComicReader(
  bookId: 'comic_1',
  pages: ComicPages.fromUrls(imageUrls),
  settings: const ReaderSettings(brightness: 0.8, keepScreenOn: true),
);

NovelReader(
  bookId: 'book_1',
  source: NovelSource.text('/path/to/book.txt'),
  settings: const ReaderSettings(
    typography: NovelTypography(fontSize: 18, lineHeight: 1.6),
    // novelReadingMode defaults to horizontal (book-style paging)
  ),
);

PdfReader(
  bookId: 'pdf_1',
  source: PdfSource.bytes(pdfBytes),
);

Feature overview #

Area Summary
Comic Multi-source / CBZ, vertical & horizontal, RTL, zoom, double-page, fit, thumbs, bookmarks, trial, watermark, ink, sync hook
Novel EPUB + txt/md/html, search, nested TOC, themes, TTS, media overlay, bookmarks/highlights, watermark, ink
PDF pdf 3.13.0 + printing raster; comic-aligned toolbar / bookmarks / trial / ink / sync
Shared Settings / progress / bookmark stores, brightness, wakelock, tap zones, progress bar, JSON export, onSync

Comic (ComicReader) #

Powered by extended_image 10.1.0.

Sources #

API Description
ComicPages.fromFiles Local image file paths
ComicPages.fromUrls Remote image URLs
ComicPages.fromBytes In-memory image bytes
ComicArchive.fromBytes CBZ/ZIP → sorted jpg/png/gif/webp/bmp pages

Reading & display #

  • Modes: ComicReadingMode.vertical / horizontal (toolbar switchable)
  • RTL: rtl (reverses horizontal swipe direction)
  • Double-page: ReaderSettings.doublePage (horizontal only)
  • Fit: ComicFitMode.contain / width / height
  • Background: black / gray / white (comicBackground)
  • Gesture zoom (~1×–4×); double-tap toggles 1× ↔ 2.5×
  • Neighbor precache (including second page in double-page)
  • Loading indicator; failed loads can retry
  • Swipe pages; drag top ReaderProgressBar; jump-to-page dialog
  • Thumbnail grid jump
  • Keyboard / volume keys (reversed under RTL)
  • Tap anywhere: toggle toolbar only (no tap-to-page; page via swipe / keys / toolbar)
  • Trial: trialLimit + onTrialLimitReached (swipe overscroll at the trial edge callbacks to host; no built-in dialog/overlay)
  • Persistence: persistProgressReaderProgressStore
  • Callbacks: onPageChanged, onSessionTick (~30s), onSync

Bookmarks & toolbar #

  • Toggle bookmark on current page; bookmark list (jump / delete)
  • Watermark: watermarkText
  • Freehand ink: enableInk
  • Optional toolbar: showToolbar; immersive chrome: immersive
  • Toolbar: page label, progress, brightness, direction, fit, double-page, bookmarks, thumbs, keep-awake, background, jump

Constructor highlights #

pages · bookId · readingMode · settings · rtl · initialPage · persistProgress · persistSettings · trialLimit · onTrialLimitReached · watermarkText · enableInk · pageTurnEffect · onPageChanged · onSettingsChanged · onSessionTick · onSync · showToolbar

ComicReader(
  bookId: 'comic_1',
  pages: ComicPages.fromUrls(urls),
  readingMode: ComicReadingMode.horizontal,
  trialLimit: ReaderTrialLimit.pages(3, startPage: 0),
  onTrialLimitReached: (event) {
    // Dialog, SnackBar, paywall, etc. — host decides
    // event.limit / currentIndex / targetIndex / totalCount / action
  },
  watermarkText: 'user@example.com',
  enableInk: true,
  onSync: (payload) async { /* upload progress / bookmarks */ },
);

Novel (NovelReader) #

EPUB and common text formats.

Sources (NovelSource) #

Format Factories
EPUB epub / epubAsset / epubUrl / epubBytes
TXT text / textAsset / textUrl / textBytes
Markdown markdown / markdownAsset
HTML html / htmlAsset

Also: NovelBytesSource.file / asset / url / bytes.

EPUB (offline epub.js + WebView) #

  • Bundled assets/epubjs/ (no CDN)
  • Flow: paginated / scrolled (follows NovelReadingMode)
  • EpubViewerController: chapters, paging, search, current CFI
  • Typography / theme colors synced into epub.js via JS bridge
  • Resume: initialCfi; onLocationChanged (CFI)
  • TOC: onChaptersLoaded / onChapterChanged

Text (txt / md / html) #

  • Encoding: UTF-8 with GBK / GB18030 fallback; optional encoding
  • Strip HTML tags; light Markdown cleanup
  • Vertical: scrollable selectable text
  • Horizontal: paragraph pagination + PageView (rtl supported)
  • Chapter heuristics: 第×章 / Chapter N / # heading
  • Search: searchParagraphsNovelSearchHit
  • APIs: jumpToParagraph / nextPage / prevPage
  • Prev/next chapter & page, chapter tree, full-text search
  • Bookmarks (CFI or paragraph index), highlights (stored excerpt; yellow on text path)
  • Font size / line height / margins / letter spacing / align
  • Font chips: NovelFontOption.defaults
  • Themes: NovelThemePreset.defaults (Cream / White / Sepia / Green / Dark / AMOLED)
  • Vertical ↔ horizontal, brightness, keep-awake
  • Auto-scroll (text path), TTS, media-overlay play/pause
  • Top progress bar seeks by chapter ratio (trial-aware readable range)
  • Keyboard / volume keys; tap anywhere toggles toolbar only (page via swipe / toolbar)
  • Trial: trialLimit (counts chapters) + onTrialLimitReached; body truncation; swipe overscroll / chapter list / search / toolbar overflow callbacks
  • Watermark / ink: watermarkText / enableInk

TTS & audio #

API Role
NovelTtsEngine Optional injection; speaks current text paragraph (toolbar toggle). Wire flutter_tts (or similar) in the host app on mobile; toolbar button hidden when omitted — macOS/desktop builds avoid the native plugin
MediaOverlayCue + MediaOverlayPlayer Timed karaoke cues; mediaOverlaySource + mediaOverlayCues; onKaraokeCue
AudiobookController Standalone playFile / playUrl (not wired into reader toolbar)
// Host app: add flutter_tts to pubspec and implement NovelTtsEngine
class FlutterTtsEngine implements NovelTtsEngine {
  FlutterTtsEngine() : _tts = FlutterTts();
  final FlutterTts _tts;
  @override
  Future<void> speak(String text) => _tts.speak(text);
  @override
  Future<void> stop() => _tts.stop();
  @override
  void setCompletionHandler(VoidCallback? handler) {
    _tts.setCompletionHandler(handler);
  }
  @override
  void dispose() {}
}

NovelReader(
  ttsEngine: FlutterTtsEngine(),
  // ...
);

Constructor highlights #

source · bookId · settings · encoding · initialCfi · persistProgress · persistSettings · trialLimit · onTrialLimitReached · watermarkText · enableInk · mediaOverlayCues · mediaOverlaySource · ttsEngine · callbacks · showToolbar · rtl

NovelReader(
  bookId: 'novel_1',
  source: NovelSource.epub('/path/to/book.epub'),
  trialLimit: ReaderTrialLimit.chapters(3, startChapter: 0),
  onTrialLimitReached: (event) { /* host UI */ },
  watermarkText: 'trial',
  enableInk: true,
  mediaOverlaySource: UrlSource('https://example.com/narration.mp3'),
  mediaOverlayCues: const [
    MediaOverlayCue(startMs: 0, endMs: 2000, paragraphIndex: 0),
  ],
  onSync: (payload) async {},
);

Export bookmarks / highlights:

final json = await ReaderBookmarkStore.instance.exportJson('novel_1');

PDF (PdfReader) #

Uses pdf 3.13.0 + printing 5.15.0: Printing.raster converts each page to a bitmap. Works on Linux / Windows / Android / iOS / macOS (desktop via printing’s bundled pdfium). Page-based features align with ComicReader (no novel-only TTS / chapter TOC / text search).

Implemented #

Feature Notes
Sources PdfSource.file / PdfSource.bytes / PdfSource.url
Render Per-page bitmap; InteractiveViewer zoom; comicFitMode
Navigation Vertical/horizontal, RTL, double-page; tap toggles toolbar; keys; progress seek; jump
Toolbar Brightness, mode, fit, double-page, bookmarks, thumbs, keep-awake, background
Brightness / wake / immersive ReaderSettings + ReaderImmersive
Watermark / ink watermarkText / enableInk
Trial trialLimit + swipe-past-end → onTrialLimitReached
Persistence persistProgress / persistSettings
Callbacks onPageChanged · onSettingsChanged · onSessionTick · onSync
Tuning rasterDpi (default 120) · readingMode · rtl
PdfReader(
  bookId: 'doc_1',
  source: PdfSource.url('https://example.com/doc.pdf'),
  // or PdfSource.file(...) / PdfSource.bytes(...)
  readingMode: ComicReadingMode.horizontal,
  rtl: false,
  trialLimit: ReaderTrialLimit.pages(5, startPage: 0),
  onTrialLimitReached: (event) { /* host UI */ },
  watermarkText: 'CONFIDENTIAL',
  enableInk: true,
  persistSettings: true,
  onSync: (payload) async { /* cloud sync */ },
  rasterDpi: 120,
);

Trial (ReaderTrialLimit) #

All three readers use trialLimit for the preview window and onTrialLimitReached to report overflow attempts. On comic/novel/PDF, swiping past the trial edge triggers the callback (tap never pages). The package does not show trial-end UI — dialogs, snackbars, and overlays are up to the host.

Configuration #

Field Meaning
maxCount Readable pages (comic/PDF) or chapters (novel)
startIndex First readable page/chapter (0-based)
unit ReaderTrialUnit.page or .chapter

Factories:

ReaderTrialLimit.pages(3, startPage: 0);       // comic / PDF
ReaderTrialLimit.chapters(3, startChapter: 0); // novel

Callback ReaderTrialLimitEvent #

Field Meaning
limit Active trial config
currentIndex Current page/chapter index
targetIndex Page/chapter the user tried to reach
totalCount Total pages/chapters
action next · seek · chapterSelect · search

Behavior summary #

Reader Unit Package behavior
Comic page Truncates PageView; swipe overscroll / seek / thumb overflow callbacks (tap does not page)
Novel chapter Truncates body paragraphs; swipe overscroll / chapter / search / toolbar overflow callbacks (tap does not page)
PDF page Truncates PageView; swipe past trial end / seek overflow callbacks (tap does not page)

Legacy helpers: trialPageCount · clampTrialPage · trialLimited · atTrialEnd.


Platform support #

Platform Comic Novel (text) Novel (EPUB) PDF
Android / iOS
Linux / Windows / macOS ✓ (webview_flutter) ✓ (printing / pdfium)
Web ✓ (URL images) ✓ (asset / url / bytes) WebView + assets required pdf.js required

Notes:

  • Linux / Windows: local file paths work; EPUB uses WebView; PDF does not rely on system WebView PDF embed.
  • Desktop TTS / system brightness may be limited (brightness falls back to overlay).
  • macOS sandbox: ComicPages.fromUrls requires com.apple.security.network.client in host entitlements for outbound HTTP/HTTPS; the example app includes this.
  • On web, NovelSource.*(path) / ComicPages.fromFiles throw UnsupportedError — use asset / url / bytes.

Shared APIs #

Settings #

API Role
ReaderSettings Brightness, keep-awake, novel typography/colors/mode, comic fit/double-page/bg, tapZonesEnabled (PDF), immersive
ReaderSettingsStore SharedPreferences persistence
NovelTypography Size, line height, font, letter spacing, align, margins
NovelThemePreset / NovelFontOption Theme & font presets

Progress / bookmarks / sync #

API Role
ReaderProgress + ReaderProgressStore Page / CFI / paragraph / percentage
ReaderBookmark / ReaderHighlight + ReaderBookmarkStore Bookmarks, highlights, exportJson
ReaderSyncHub / ReaderSyncPayload / onSync Host hook after local changes (no built-in upload)

Display & interaction #

API Role
ReaderBrightness / BrightnessOverlay System brightness with overlay fallback
ReaderWakeLock wakelock_plus
ReaderImmersive Immersive system UI
TapZoneDetector / TapZoneAction Legacy helpers; comic / novel / PDF taps toggle toolbar only
ReaderProgressBar Top progress bar
ReaderWatermark Watermark overlay
ReaderTrialLimit / ReaderTrialLimitEvent / onTrialLimitReached Trial window + overflow callback
trialPageCount / clampTrialPage / trialLimited / atTrialEnd Trial helpers (wrap ReaderTrialLimit.pages)
InkAnnotationLayer / InkStroke Freehand ink, undo/clear, JSON
PageCurl / CurlPageView / PageTurnEffect Page-curl helpers (standalone)
MediaOverlayPlayer / AudiobookController Audio + karaoke

Known limitations #

Item Status
ComicReader.pageTurnEffect Declared; comic path still uses ExtendedImageGesturePageView — use CurlPageView yourself
Comic double-page Horizontal only; enabling double-page auto-switches from vertical
EPUB trial Chapter-level blocking + callbacks; in-book paging may need host handling at deep jumps
EPUB TTS Text path speaks current paragraph; EPUB does not read body text
Auto-scroll Text path only
Media overlay → EPUB Karaoke jumps by paragraph, not CFI
Novel bookmark/highlight list UI Persist yes; no list sheet (comic has bookmark list)
Ink Drawable via enableInk; no toolbar undo/clear; not persisted by default
Large PDFs Page rasterization; high page count / rasterDpi increases memory and load time
Android PDF System PdfRenderer requires PDF 1.7+, unencrypted; older/hand-written PDFs may fail
Markdown / HTML URL No *Url factories (file / asset only)
Local file paths May UnsupportedError on web — prefer asset / url / bytes
onSync Host hook only; no cloud upload inside the package

Example app #

cd example
flutter pub get
flutter run
Entry Demo
Comic Remote images, 3-page trial (default dialog feedback), ink, onSync snackbar, bookmark export
Novel (text) 12-chapter sample, 3-chapter trial, themes / TTS, JSON export, sync
PDF PdfSource.url sample; full toolbar / bookmarks / ink / sync / trial demo

Example Advanced settings configure trial count, start page/chapter, and feedback style (dialog / SnackBar / none).


Changelog #

See CHANGELOG.md / CHANGELOG_zh.md.


[Support the author]

If you find this project helpful, please consider supporting me.

0
likes
160
points
236
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Cross-platform Flutter comic and novel reader package.

Homepage

License

MIT (license)

Dependencies

archive, audioplayers, charset_converter, extended_image, flutter, http, material_ui, path_provider, pdf, printing, screen_brightness, shared_preferences, wakelock_plus, webview_flutter

More

Packages that depend on phantasm_read