Stage 6 행성에 자기장 라인이 행성을 감싸며 바깥으로 번지는 연출

This commit is contained in:
Sn-Kinos
2026-10-22 01:25:27 +09:00
parent a2739a37f1
commit 6a1f97fbc2
2 changed files with 80 additions and 0 deletions
+62
View File
@@ -472,6 +472,21 @@ class _Planet25DState extends State<Planet25D>
), ),
), ),
), ),
// Stage 6 — Figma `2024:20821` 「자기장(Field) 라인이 행성을 감싸며 외곽으로 방사됨」.
// 본체 뒤에 깔아 구면 바깥으로 뻗는 부분만 보이게 한다.
if (stage == 6)
Positioned.fill(
child: IgnorePointer(
child: CustomPaint(
key: const ValueKey('planet-field-lines'),
painter: _FieldLinePainter(
t: t,
color: glow,
lowEffects: _lowEffects,
),
),
),
),
// 6. 링 — 뒤쪽 절반. 본체 뒤에 깔린다. // 6. 링 — 뒤쪽 절반. 본체 뒤에 깔린다.
if (ring) if (ring)
Positioned.fill( Positioned.fill(
@@ -902,6 +917,53 @@ class _OrbitPainter extends CustomPainter {
old.lowEffects != lowEffects; old.lowEffects != lowEffects;
} }
/// Stage 6 자기장 — 양극을 잇는 고리를 좌우로 겹겹이 그리고, 밝은 띠가 안쪽에서 바깥 고리로
/// 번져 나간다(외곽 방사). 저사양은 고리 수만 줄인다.
class _FieldLinePainter extends CustomPainter {
const _FieldLinePainter({
required this.t,
required this.color,
required this.lowEffects,
});
final double t;
final Color color;
final bool lowEffects;
@override
void paint(Canvas canvas, Size size) {
final c = size.center(Offset.zero);
final r = size.shortestSide * 0.42;
final loops = lowEffects ? 2 : 4;
// 방사 위치 0~1 — 한 주기에 네 번 안쪽에서 바깥으로.
final wave = (t * 4) % 1;
for (var i = 0; i < loops; i++) {
final k = (i + 1) / loops;
final w = r * (0.55 + 0.75 * k);
final h = r * (1.05 + 0.25 * k);
final glow = 1 - ((k - wave).abs() * 2.5).clamp(0.0, 1.0);
final paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1.0 + glow * 1.2
..color = Color.lerp(color, Colors.white, 0.35)!
.withValues(alpha: (0.14 + 0.36 * glow) * (1 - k * 0.4));
for (final side in const [-1.0, 1.0]) {
canvas.drawOval(
Rect.fromCenter(
center: c + Offset(side * w / 2, 0),
width: w,
height: h * 2,
),
paint,
);
}
}
}
@override
bool shouldRepaint(_FieldLinePainter old) =>
old.t != t || old.color != color || old.lowEffects != lowEffects;
}
/// Stage 6: 폭죽 대신 구면 주위에 머무는 넓고 일정한 대기광. /// Stage 6: 폭죽 대신 구면 주위에 머무는 넓고 일정한 대기광.
class _SustainedAura extends CustomPainter { class _SustainedAura extends CustomPainter {
const _SustainedAura({required this.color, required this.lowEffects}); const _SustainedAura({required this.color, required this.lowEffects});
+18
View File
@@ -182,4 +182,22 @@ void main() {
await tester.pump(const Duration(seconds: 3)); await tester.pump(const Duration(seconds: 3));
}); });
}); });
testWidgets('Stage 6 은 자기장 라인이 행성을 감싼다(Figma 2024:20821) · Stage 5 는 없다', (tester) async {
Future<void> pumpStage(int stage) => tester.pumpWidget(
MaterialApp(
home: Center(
child: Planet25D(
image: 'assets/figma/planet-home.png',
size: 200,
stage: stage,
),
),
),
);
await pumpStage(6);
expect(find.byKey(const ValueKey('planet-field-lines')), findsOneWidget);
await pumpStage(5);
expect(find.byKey(const ValueKey('planet-field-lines')), findsNothing);
});
} }