feat(f3): viewport fit/centering math (fit-width / fit-page / center)
Some checks failed
CI / Windows build (push) Has been cancelled
Some checks failed
CI / Windows build (push) Has been cancelled
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>
This commit is contained in:
49
test/viewport_fit_test.dart
Normal file
49
test/viewport_fit_test.dart
Normal file
@@ -0,0 +1,49 @@
|
||||
// Tests for viewport fit/centering math (F3).
|
||||
|
||||
import 'dart:ui' show Offset, Size;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:badnote/editor/layout/viewport_fit.dart';
|
||||
|
||||
void main() {
|
||||
test('fitWidthScale fills the viewport width', () {
|
||||
expect(fitWidthScale(const Size(500, 800), 1000), 2.0);
|
||||
expect(fitWidthScale(const Size(0, 800), 1000), 0);
|
||||
});
|
||||
|
||||
test('fitPageScale is the limiting (min) axis, letterboxed', () {
|
||||
// content 500x1000 into 1000x1000: w-fit=2, h-fit=1 → min 1.
|
||||
expect(fitPageScale(const Size(500, 1000), const Size(1000, 1000)), 1.0);
|
||||
// content 1000x500 into 1000x1000: w-fit=1, h-fit=2 → min 1.
|
||||
expect(fitPageScale(const Size(1000, 500), const Size(1000, 1000)), 1.0);
|
||||
expect(fitPageScale(const Size(0, 0), const Size(100, 100)), 0);
|
||||
});
|
||||
|
||||
test('centerOffset centers smaller content', () {
|
||||
// content 200x100 at scale 1 in 1000x600 → offset (400, 250).
|
||||
expect(
|
||||
centerOffset(const Size(200, 100), const Size(1000, 600), 1.0),
|
||||
const Offset(400, 250),
|
||||
);
|
||||
});
|
||||
|
||||
test('centerOffset is negative when scaled content overflows', () {
|
||||
// content 1000x1000 at scale 2 = 2000 in a 1000 viewport → (-500, -500).
|
||||
expect(
|
||||
centerOffset(const Size(1000, 1000), const Size(1000, 1000), 2.0),
|
||||
const Offset(-500, -500),
|
||||
);
|
||||
});
|
||||
|
||||
test('fit-to-width then center yields a left-anchored x for a tall page', () {
|
||||
const content = Size(500, 2000);
|
||||
const viewport = Size(1000, 800);
|
||||
final scale = fitWidthScale(content, viewport.width); // 2.0
|
||||
final off = centerOffset(content, viewport, scale);
|
||||
// Scaled width = 1000 == viewport width → x offset 0.
|
||||
expect(off.dx, 0);
|
||||
// Scaled height 4000 > 800 → negative y (overflows, scrollable).
|
||||
expect(off.dy, lessThan(0));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user