Stage 6 행성에 자기장 라인이 행성을 감싸며 바깥으로 번지는 연출
This commit is contained in:
@@ -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. 링 — 뒤쪽 절반. 본체 뒤에 깔린다.
|
||||
if (ring)
|
||||
Positioned.fill(
|
||||
@@ -902,6 +917,53 @@ class _OrbitPainter extends CustomPainter {
|
||||
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: 폭죽 대신 구면 주위에 머무는 넓고 일정한 대기광.
|
||||
class _SustainedAura extends CustomPainter {
|
||||
const _SustainedAura({required this.color, required this.lowEffects});
|
||||
|
||||
@@ -182,4 +182,22 @@ void main() {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user