From c59454aa5f0a211e09ce1a515ec4aa3f965aa185 Mon Sep 17 00:00:00 2001 From: airkjw Date: Fri, 12 Jun 2026 07:37:54 +0900 Subject: [PATCH] fix: center splash logo and wordmark (stack was sized to children) Wrap AnimatedBuilder in SizedBox.expand so the Stack fills the full Scaffold body; alignment: Alignment.center now centers within the whole screen instead of within the wordmark-sized intrinsic box. Adds a regression widget test (test/ui/splash_screen_test.dart) that asserts the wordmark dx is within 1px of screen-center at 1500ms into the animation. Co-Authored-By: Claude Sonnet 4.6 --- lib/ui/screens/splash_screen.dart | 52 ++++++++++++++++--------------- test/ui/splash_screen_test.dart | 19 +++++++++++ 2 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 test/ui/splash_screen_test.dart diff --git a/lib/ui/screens/splash_screen.dart b/lib/ui/screens/splash_screen.dart index 195830c..c8b06d5 100644 --- a/lib/ui/screens/splash_screen.dart +++ b/lib/ui/screens/splash_screen.dart @@ -57,34 +57,36 @@ class _SplashScreenState extends State const gap = 3.0; return Scaffold( backgroundColor: const Color(0xFF0E1430), - body: AnimatedBuilder( - animation: _c, - builder: (context, _) { - final titleT = const Interval(0.60, 0.88, curve: Curves.easeOut) - .transform(_c.value); - return Stack( - alignment: Alignment.center, - children: [ - for (var i = 0; i < _blocks.length; i++) - _block(i, blockSize, gap), - Transform.translate( - offset: Offset(0, 78 + 12 * (1 - titleT)), - child: Opacity( - opacity: titleT, - child: const Text( - 'BLOCK SEASONS', - style: TextStyle( - fontSize: 26, - fontWeight: FontWeight.w900, - letterSpacing: 4, - color: Colors.white, + body: SizedBox.expand( + child: AnimatedBuilder( + animation: _c, + builder: (context, _) { + final titleT = const Interval(0.60, 0.88, curve: Curves.easeOut) + .transform(_c.value); + return Stack( + alignment: Alignment.center, + children: [ + for (var i = 0; i < _blocks.length; i++) + _block(i, blockSize, gap), + Transform.translate( + offset: Offset(0, 78 + 12 * (1 - titleT)), + child: Opacity( + opacity: titleT, + child: const Text( + 'BLOCK SEASONS', + style: TextStyle( + fontSize: 26, + fontWeight: FontWeight.w900, + letterSpacing: 4, + color: Colors.white, + ), ), ), ), - ), - ], - ); - }, + ], + ); + }, + ), ), ); } diff --git a/test/ui/splash_screen_test.dart b/test/ui/splash_screen_test.dart new file mode 100644 index 0000000..f76bc54 --- /dev/null +++ b/test/ui/splash_screen_test.dart @@ -0,0 +1,19 @@ +import 'package:block_seasons/ui/screens/splash_screen.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('splash wordmark is horizontally centered', (tester) async { + await tester.pumpWidget(MaterialApp( + home: SplashScreen(nextScreen: () => const Scaffold(body: SizedBox())), + )); + // Mid-animation: wordmark already laid out. + await tester.pump(const Duration(milliseconds: 1500)); + final screenWidth = tester.getSize(find.byType(SplashScreen)).width; + final wordmark = tester.getCenter(find.text('BLOCK SEASONS')); + expect(wordmark.dx, closeTo(screenWidth / 2, 1.0)); + // Drain the rest of the animation so no timers leak. + await tester.pump(const Duration(milliseconds: 600)); + await tester.pumpAndSettle(); + }); +}