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 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 07:37:54 +09:00
parent bf7720ebd3
commit c59454aa5f
2 changed files with 46 additions and 25 deletions
+27 -25
View File
@@ -57,34 +57,36 @@ class _SplashScreenState extends State<SplashScreen>
const gap = 3.0; const gap = 3.0;
return Scaffold( return Scaffold(
backgroundColor: const Color(0xFF0E1430), backgroundColor: const Color(0xFF0E1430),
body: AnimatedBuilder( body: SizedBox.expand(
animation: _c, child: AnimatedBuilder(
builder: (context, _) { animation: _c,
final titleT = const Interval(0.60, 0.88, curve: Curves.easeOut) builder: (context, _) {
.transform(_c.value); final titleT = const Interval(0.60, 0.88, curve: Curves.easeOut)
return Stack( .transform(_c.value);
alignment: Alignment.center, return Stack(
children: [ alignment: Alignment.center,
for (var i = 0; i < _blocks.length; i++) children: [
_block(i, blockSize, gap), for (var i = 0; i < _blocks.length; i++)
Transform.translate( _block(i, blockSize, gap),
offset: Offset(0, 78 + 12 * (1 - titleT)), Transform.translate(
child: Opacity( offset: Offset(0, 78 + 12 * (1 - titleT)),
opacity: titleT, child: Opacity(
child: const Text( opacity: titleT,
'BLOCK SEASONS', child: const Text(
style: TextStyle( 'BLOCK SEASONS',
fontSize: 26, style: TextStyle(
fontWeight: FontWeight.w900, fontSize: 26,
letterSpacing: 4, fontWeight: FontWeight.w900,
color: Colors.white, letterSpacing: 4,
color: Colors.white,
),
), ),
), ),
), ),
), ],
], );
); },
}, ),
), ),
); );
} }
+19
View File
@@ -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();
});
}