fix(new-character): 캐릭터 생성 화면 UX 개선
- 굴리기 버튼 연속 클릭 방지 (100ms 딜레이) - 스크롤 애니메이션 대신 jumpTo 사용 (WASM 안정성) - Row를 Wrap으로 변경하여 버튼 레이아웃 개선
This commit is contained in:
@@ -61,6 +61,9 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
|||||||
// 테스트 모드 (웹에서 모바일 캐로셀 레이아웃 활성화)
|
// 테스트 모드 (웹에서 모바일 캐로셀 레이아웃 활성화)
|
||||||
bool _testModeEnabled = false;
|
bool _testModeEnabled = false;
|
||||||
|
|
||||||
|
// 굴리기 버튼 연속 클릭 방지
|
||||||
|
bool _isRolling = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -96,23 +99,22 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
|||||||
const itemHeight = 48.0;
|
const itemHeight = 48.0;
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (!mounted) return;
|
||||||
|
|
||||||
|
// 스크롤 애니메이션 대신 즉시 점프 (WASM 모드 안정성)
|
||||||
if (_raceScrollController.hasClients) {
|
if (_raceScrollController.hasClients) {
|
||||||
final raceOffset = _selectedRaceIndex * itemHeight;
|
final raceOffset = _selectedRaceIndex * itemHeight;
|
||||||
_raceScrollController.animateTo(
|
_raceScrollController.jumpTo(
|
||||||
raceOffset.clamp(0.0, _raceScrollController.position.maxScrollExtent),
|
raceOffset.clamp(0.0, _raceScrollController.position.maxScrollExtent),
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
curve: Curves.easeOut,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (_klassScrollController.hasClients) {
|
if (_klassScrollController.hasClients) {
|
||||||
final klassOffset = _selectedKlassIndex * itemHeight;
|
final klassOffset = _selectedKlassIndex * itemHeight;
|
||||||
_klassScrollController.animateTo(
|
_klassScrollController.jumpTo(
|
||||||
klassOffset.clamp(
|
klassOffset.clamp(
|
||||||
0.0,
|
0.0,
|
||||||
_klassScrollController.position.maxScrollExtent,
|
_klassScrollController.position.maxScrollExtent,
|
||||||
),
|
),
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
curve: Curves.easeOut,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -134,6 +136,10 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
|||||||
/// Re-Roll 버튼 클릭
|
/// Re-Roll 버튼 클릭
|
||||||
/// 원본 NewGuy.pas RerollClick: 스탯, 종족, 클래스 모두 랜덤화
|
/// 원본 NewGuy.pas RerollClick: 스탯, 종족, 클래스 모두 랜덤화
|
||||||
void _onReroll() {
|
void _onReroll() {
|
||||||
|
// 연속 클릭 방지
|
||||||
|
if (_isRolling) return;
|
||||||
|
_isRolling = true;
|
||||||
|
|
||||||
// 현재 시드를 이력에 저장
|
// 현재 시드를 이력에 저장
|
||||||
_rollHistory.insert(0, _currentSeed);
|
_rollHistory.insert(0, _currentSeed);
|
||||||
|
|
||||||
@@ -156,6 +162,11 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
|||||||
|
|
||||||
// 선택된 종족/직업으로 스크롤
|
// 선택된 종족/직업으로 스크롤
|
||||||
_scrollToSelectedItems();
|
_scrollToSelectedItems();
|
||||||
|
|
||||||
|
// 짧은 딜레이 후 다시 클릭 가능
|
||||||
|
Future.delayed(const Duration(milliseconds: 100), () {
|
||||||
|
if (mounted) _isRolling = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unroll 버튼 클릭 (이전 롤로 복원)
|
/// Unroll 버튼 클릭 (이전 롤로 복원)
|
||||||
@@ -401,8 +412,10 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
|||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
|
|
||||||
// Roll 버튼들
|
// Roll 버튼들
|
||||||
Row(
|
Wrap(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
alignment: WrapAlignment.center,
|
||||||
|
spacing: 16,
|
||||||
|
runSpacing: 8,
|
||||||
children: [
|
children: [
|
||||||
OutlinedButton.icon(
|
OutlinedButton.icon(
|
||||||
onPressed: _onUnroll,
|
onPressed: _onUnroll,
|
||||||
@@ -412,7 +425,6 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
|||||||
foregroundColor: _rollHistory.isEmpty ? Colors.grey : null,
|
foregroundColor: _rollHistory.isEmpty ? Colors.grey : null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
|
||||||
FilledButton.icon(
|
FilledButton.icon(
|
||||||
onPressed: _onReroll,
|
onPressed: _onReroll,
|
||||||
icon: const Icon(Icons.casino),
|
icon: const Icon(Icons.casino),
|
||||||
|
|||||||
Reference in New Issue
Block a user