갤럭시 검색 결과에서 행성 상세로 이동
This commit is contained in:
@@ -73,12 +73,20 @@ class GalaxyField extends StatelessWidget {
|
||||
/// 90개가 사라진다. 바깥 궤도가 [edgeMargin] 안쪽에 서도록 간격을 나눈다.
|
||||
static double ringOf(int rank, int outerRank) {
|
||||
final rings = math.max(1, outerRank - 1);
|
||||
final gap = math.min(ringGap, (extent / 2 - innerRing - edgeMargin) / rings);
|
||||
final gap = math.min(
|
||||
ringGap,
|
||||
(extent / 2 - innerRing - edgeMargin) / rings,
|
||||
);
|
||||
return innerRing + (rank - 1) * gap;
|
||||
}
|
||||
|
||||
/// 행성의 논리 좌표. 그리기·히트 테스트·HUD 가 같은 식을 써야 어긋나지 않는다.
|
||||
static Offset positionOf(PlanetNode p, int index, double spin, int outerRank) {
|
||||
static Offset positionOf(
|
||||
PlanetNode p,
|
||||
int index,
|
||||
double spin,
|
||||
int outerRank,
|
||||
) {
|
||||
if (p.isCenter) return const Offset(extent / 2, extent / 2);
|
||||
// 순위가 낮을수록 멀어진다. 중심 행성을 뺀 나머지를 고리에 흩는다.
|
||||
final ring = ringOf(p.rank, outerRank);
|
||||
@@ -101,7 +109,10 @@ class GalaxyField extends StatelessWidget {
|
||||
|
||||
/// -1(뒤·화면 위) ~ +1(앞·화면 아래) 의 깊이.
|
||||
static double depthOf(Offset at) =>
|
||||
((at.dy - extent / 2) / (extent / 2 * GalaxyMotion.tilt)).clamp(-1.0, 1.0);
|
||||
((at.dy - extent / 2) / (extent / 2 * GalaxyMotion.tilt)).clamp(
|
||||
-1.0,
|
||||
1.0,
|
||||
);
|
||||
|
||||
/// 2.5D 깊이 배율. 궤도 앞쪽일수록 크다.
|
||||
static double depthScaleOf(Offset at) =>
|
||||
@@ -125,7 +136,9 @@ class GalaxyField extends StatelessWidget {
|
||||
/// 행성 일러스트. 내 행성은 홈과 같은 그림, 나머지는 시안 행성 2종을 돌려 쓴다.
|
||||
static String imageOf(PlanetNode p, int index) => p.isMine
|
||||
? 'assets/figma/planet-home.png'
|
||||
: (index.isEven ? 'assets/figma/planet-1.png' : 'assets/figma/planet-2.png');
|
||||
: (index.isEven
|
||||
? 'assets/figma/planet-1.png'
|
||||
: 'assets/figma/planet-2.png');
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -147,7 +160,10 @@ class GalaxyField extends StatelessWidget {
|
||||
Positioned.fill(
|
||||
child: RepaintBoundary(
|
||||
child: CustomPaint(
|
||||
painter: _BackdropPainter(planets: planets, outerRank: outerRank),
|
||||
painter: _BackdropPainter(
|
||||
planets: planets,
|
||||
outerRank: outerRank,
|
||||
),
|
||||
isComplex: true,
|
||||
willChange: false,
|
||||
),
|
||||
@@ -169,7 +185,9 @@ class GalaxyField extends StatelessWidget {
|
||||
opacity: depthOpacityOf(at),
|
||||
selected: selected?.id == p.id,
|
||||
onTap: () => onSelect(p),
|
||||
onOpenHistory: onOpenHistory == null ? null : () => onOpenHistory!(p),
|
||||
onOpenHistory: onOpenHistory == null
|
||||
? null
|
||||
: () => onOpenHistory!(p),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -243,8 +261,17 @@ class _PlanetHit extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
// 3~5. 본체 일러스트(표면 장식·구름 포함).
|
||||
LivePlanet25D(onOpenHistory: onOpenHistory, fandomId: planet.id, watch: watchPlanet, image: image, size: side, stage: planet.stage, glow: glow,
|
||||
animate: selected, lowEffects: !selected),
|
||||
LivePlanet25D(
|
||||
onOpenHistory: onOpenHistory,
|
||||
fandomId: planet.id,
|
||||
watch: watchPlanet,
|
||||
image: image,
|
||||
size: side,
|
||||
stage: planet.stage,
|
||||
glow: glow,
|
||||
animate: selected,
|
||||
lowEffects: !selected,
|
||||
),
|
||||
Positioned(
|
||||
bottom: -4,
|
||||
child: Text(
|
||||
@@ -257,7 +284,9 @@ class _PlanetHit extends StatelessWidget {
|
||||
fontWeight: planet.isMine
|
||||
? FontWeight.w600
|
||||
: FontWeight.w400,
|
||||
shadows: const [Shadow(color: Colors.black, blurRadius: 6)],
|
||||
shadows: const [
|
||||
Shadow(color: Colors.black, blurRadius: 6),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -309,7 +338,8 @@ class _BackdropPainter extends CustomPainter {
|
||||
|
||||
static bool _sameRanks(List<PlanetNode> a, List<PlanetNode> b) {
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if (a[i].rank != b[i].rank || a[i].isCenter != b[i].isCenter) return false;
|
||||
if (a[i].rank != b[i].rank || a[i].isCenter != b[i].isCenter)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,8 @@ class _GalaxyWebViewState extends State<GalaxyWebView>
|
||||
}
|
||||
|
||||
bool get _visible {
|
||||
if (!mounted || !_foreground || !TickerMode.valuesOf(context).enabled) return false;
|
||||
if (!mounted || !_foreground || !TickerMode.valuesOf(context).enabled)
|
||||
return false;
|
||||
if (ModalRoute.of(context)?.isCurrent == false) return false;
|
||||
final box = context.findRenderObject();
|
||||
if (box is! RenderBox || !box.attached || !box.hasSize) return true;
|
||||
|
||||
@@ -80,7 +80,8 @@ class _ZapButtonState extends State<ZapButton> {
|
||||
}
|
||||
|
||||
bool get _canZap =>
|
||||
widget.blockedReason == null && (widget.isHeroTime || widget.myPop >= widget.zapPop);
|
||||
widget.blockedReason == null &&
|
||||
(widget.isHeroTime || widget.myPop >= widget.zapPop);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => AnimatedSize(
|
||||
@@ -180,7 +181,9 @@ class _ZapButtonState extends State<ZapButton> {
|
||||
icon: const Icon(Icons.bolt),
|
||||
label: Text(
|
||||
_canZap
|
||||
? widget.isHeroTime ? 'ZAP+ · HERO TIME' : 'ZAP ${widget.zapPop} POP'
|
||||
? widget.isHeroTime
|
||||
? 'ZAP+ · HERO TIME'
|
||||
: 'ZAP ${widget.zapPop} POP'
|
||||
: (widget.blockedReason ?? context.l10n.zapNotEnoughPop),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user