Files
BadNote/lib/editor/layout/viewport_fit.dart
Akiba So 2edb897000
Some checks failed
CI / Windows build (push) Has been cancelled
feat(f3): viewport fit/centering math (fit-width / fit-page / center)
Extracts the untested ad-hoc arithmetic from pen_editor_screen._centerPage into
pure, shared, tested functions: fitWidthScale (fill viewport width — the
continuous-single default), fitPageScale (letterboxed min-axis fit), and
centerOffset (top-left translation to center scaled content; negative when it
overflows/scrolls). Powers the viewport's initial transform + the reader
fit-width/fit-page actions.

flutter analyze lib/editor clean; 228/228 tests (+5).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 03:42:44 +08:00

40 lines
1.6 KiB
Dart

// lib/editor/layout/viewport_fit.dart
//
// Pure fit/centering math for the viewport's initial transform + the reader
// "fit width / fit page" actions (F3). Today this lives as untested ad-hoc
// arithmetic in pen_editor_screen._centerPage; extracting it here makes it
// testable and shared by the new viewport widget.
//
// Content coordinates are scale-1 logical px; the returned scale + offset place
// content inside the viewport. No widgets beyond dart:ui Size/Offset.
import 'dart:ui' show Offset, Size;
/// Scale so content width fills the viewport width (fit-to-width, the
/// continuous-single default). 0 for non-positive content width.
double fitWidthScale(Size content, double viewportWidth) {
if (content.width <= 0) return 0;
return viewportWidth / content.width;
}
/// Scale so the whole content fits inside the viewport (letterboxed) —
/// min(widthFit, heightFit). 0 for non-positive content extents.
double fitPageScale(Size content, Size viewport) {
if (content.width <= 0 || content.height <= 0) return 0;
final w = viewport.width / content.width;
final h = viewport.height / content.height;
return w < h ? w : h;
}
/// Top-left translation that centers [content] scaled by [scale] within
/// [viewport]. When the scaled content is larger than the viewport on an axis
/// the offset is negative (content overflows equally on both sides).
Offset centerOffset(Size content, Size viewport, double scale) {
final scaledW = content.width * scale;
final scaledH = content.height * scale;
return Offset(
(viewport.width - scaledW) / 2.0,
(viewport.height - scaledH) / 2.0,
);
}