draw updates
This commit is contained in:
parent
b1ecd70f8a
commit
ac9a0389d1
|
|
@ -569,284 +569,195 @@ class _SlotMachineDrawAnimationState extends State<SlotMachineDrawAnimation>
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final winnerName = _winnerId != null
|
||||
? widget.members.firstWhere((m) => m['id'] == _winnerId)['name']
|
||||
: null;
|
||||
|
||||
return Container(
|
||||
width: 300.w,
|
||||
width: 320.w,
|
||||
height: 520.h,
|
||||
child: Column(
|
||||
children: [
|
||||
// Title
|
||||
Text(
|
||||
'Slot Machine Draw',
|
||||
style: TextStyle(
|
||||
fontSize: 20.sp,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.orange.shade700,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20.h),
|
||||
|
||||
// Pointer/Indicator
|
||||
Container(
|
||||
width: 280.w,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.keyboard_arrow_down,
|
||||
color: Colors.red.shade600,
|
||||
size: 30.w,
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
Text(
|
||||
_isAnimating ? 'Selecting...' : 'Winner!',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: _isAnimating ? Colors.orange.shade600 : Colors.green.shade600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
Icon(
|
||||
Icons.keyboard_arrow_down,
|
||||
color: Colors.red.shade600,
|
||||
size: 30.w,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 10.h),
|
||||
|
||||
// Slot Machine Display
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: 280.w,
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade800,
|
||||
borderRadius: BorderRadius.circular(16.r),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Colors.grey.shade900,
|
||||
Colors.grey.shade800,
|
||||
],
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20.r),
|
||||
border: Border.all(color: Colors.orange.shade400, width: 3.w),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.3),
|
||||
blurRadius: 15.r,
|
||||
offset: Offset(0, 8.h),
|
||||
color: Colors.black.withOpacity(0.35),
|
||||
blurRadius: 18.r,
|
||||
offset: Offset(0, 10.h),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
// Slot Windows
|
||||
Expanded(
|
||||
child: Container(
|
||||
margin: EdgeInsets.all(16.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black,
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
// Animated names
|
||||
AnimatedBuilder(
|
||||
animation: _slotAnimation,
|
||||
builder: (context, child) {
|
||||
return Column(
|
||||
children: List.generate(7, (index) {
|
||||
final displayIndex = index < _displayNames.length ? index : 0;
|
||||
final name = _displayNames[displayIndex];
|
||||
final isWinner = _isComplete && index == 3; // Center position (middle of 7)
|
||||
final isCenterHighlight = _isAnimating && index == 3; // Always highlight center
|
||||
child: Container(
|
||||
margin: EdgeInsets.all(18.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
AnimatedBuilder(
|
||||
animation: _slotAnimation,
|
||||
builder: (context, child) {
|
||||
return Column(
|
||||
children: List.generate(7, (index) {
|
||||
final displayIndex = index < _displayNames.length ? index : 0;
|
||||
final name = _displayNames[displayIndex];
|
||||
final isWinner = _isComplete && index == 3;
|
||||
final isCenterHighlight = _isAnimating && index == 3;
|
||||
|
||||
return Expanded(
|
||||
child: AnimatedBuilder(
|
||||
animation: _pulseAnimation,
|
||||
builder: (context, child) {
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeInOut,
|
||||
transform: Matrix4.identity()
|
||||
..scale(isCenterHighlight || isWinner ? 1.05 : 1.0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
margin: EdgeInsets.symmetric(vertical: 2.h, horizontal: 4.w),
|
||||
decoration: BoxDecoration(
|
||||
gradient: isWinner
|
||||
? LinearGradient(
|
||||
colors: [
|
||||
Colors.green.shade600,
|
||||
Colors.green.shade700,
|
||||
],
|
||||
)
|
||||
: isCenterHighlight
|
||||
? LinearGradient(
|
||||
colors: [
|
||||
Colors.orange.shade600,
|
||||
Colors.red.shade600,
|
||||
],
|
||||
)
|
||||
: LinearGradient(
|
||||
colors: [
|
||||
Colors.blue.shade700,
|
||||
Colors.blue.shade800,
|
||||
],
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
border: Border.all(
|
||||
color: isWinner || isCenterHighlight
|
||||
? Colors.white.withOpacity(0.6)
|
||||
: Colors.white.withOpacity(0.1),
|
||||
width: isWinner || isCenterHighlight ? 2.w : 1.w,
|
||||
),
|
||||
boxShadow: isWinner
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Colors.green.shade300,
|
||||
blurRadius: 12.r,
|
||||
spreadRadius: 3.r,
|
||||
),
|
||||
]
|
||||
: isCenterHighlight
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Colors.orange.shade300.withOpacity(0.6),
|
||||
blurRadius: 8.r,
|
||||
spreadRadius: 2.r,
|
||||
),
|
||||
]
|
||||
: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.3),
|
||||
blurRadius: 4.r,
|
||||
offset: Offset(0, 2.h),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
name.length > 15 ? '${name.substring(0, 15)}...' : name,
|
||||
style: TextStyle(
|
||||
fontSize: isWinner || isCenterHighlight ? 16.sp : 13.sp,
|
||||
fontWeight: isWinner || isCenterHighlight
|
||||
? FontWeight.w900
|
||||
: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
letterSpacing: 0.5,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
blurRadius: 3.r,
|
||||
offset: Offset(1, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
return Expanded(
|
||||
child: AnimatedBuilder(
|
||||
animation: _pulseAnimation,
|
||||
builder: (context, child) {
|
||||
final double scale = isWinner || isCenterHighlight ? 1.08 : 1.0;
|
||||
final double fontSize = isWinner
|
||||
? 24.sp
|
||||
: isCenterHighlight
|
||||
? 20.sp
|
||||
: 18.sp;
|
||||
final FontWeight weight = isWinner
|
||||
? FontWeight.w900
|
||||
: isCenterHighlight
|
||||
? FontWeight.w800
|
||||
: FontWeight.w700;
|
||||
final List<Color> colors = isWinner
|
||||
? [Colors.green.shade500, Colors.green.shade600]
|
||||
: isCenterHighlight
|
||||
? [Colors.deepPurple.shade500, Colors.deepPurple.shade700]
|
||||
: [Colors.blueGrey.shade700, Colors.blueGrey.shade900];
|
||||
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 220),
|
||||
curve: Curves.easeInOut,
|
||||
transform: Matrix4.identity()..scale(scale),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
margin: EdgeInsets.symmetric(
|
||||
vertical: 6.h,
|
||||
horizontal: 12.w,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: colors,
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
border: Border.all(
|
||||
color: Colors.white.withOpacity(isWinner || isCenterHighlight ? 0.7 : 0.15),
|
||||
width: isWinner || isCenterHighlight ? 2.w : 1.w,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.4),
|
||||
blurRadius: isWinner ? 14.r : 6.r,
|
||||
offset: Offset(0, 3.h),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
// Winner highlight
|
||||
if (_isComplete)
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
height: 60.h,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.green.shade400.withOpacity(0.3),
|
||||
borderRadius: BorderRadius.circular(4.r),
|
||||
),
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.emoji_events, color: Colors.yellow, size: 24.w),
|
||||
SizedBox(width: 8.w),
|
||||
Text(
|
||||
'WINNER!',
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.yellow,
|
||||
],
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
name.length > 22 ? '${name.substring(0, 22)}…' : name,
|
||||
style: TextStyle(
|
||||
fontSize: fontSize,
|
||||
fontWeight: weight,
|
||||
color: Colors.white,
|
||||
letterSpacing: 0.6,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
blurRadius: 4.r,
|
||||
offset: Offset(1.5, 1.5),
|
||||
),
|
||||
],
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (_isComplete)
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
height: 70.h,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.green.shade400.withOpacity(0.35),
|
||||
borderRadius: BorderRadius.circular(6.r),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.emoji_events, color: Colors.yellowAccent, size: 26.w),
|
||||
SizedBox(width: 10.w),
|
||||
Text(
|
||||
'WINNER',
|
||||
style: TextStyle(
|
||||
fontSize: 20.sp,
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Colors.yellowAccent,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Slot Machine Controls
|
||||
Container(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Container(
|
||||
width: 40.w,
|
||||
height: 40.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red.shade600,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(Icons.stop, color: Colors.white, size: 20.w),
|
||||
),
|
||||
Container(
|
||||
width: 40.w,
|
||||
height: 40.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.green.shade600,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(Icons.play_arrow, color: Colors.white, size: 20.w),
|
||||
),
|
||||
Container(
|
||||
width: 40.w,
|
||||
height: 40.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue.shade600,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(Icons.pause, color: Colors.white, size: 20.w),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Status
|
||||
SizedBox(height: 20.h),
|
||||
if (_isAnimating)
|
||||
Text(
|
||||
'Slot machine spinning...',
|
||||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
color: Colors.orange.shade600,
|
||||
SizedBox(height: 16.h),
|
||||
if (_isComplete && winnerName != null)
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.green.shade50,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
)
|
||||
else if (_isComplete)
|
||||
Text(
|
||||
'Winner: ${widget.members.firstWhere((m) => m['id'] == _winnerId)['name']}',
|
||||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
color: Colors.green.shade600,
|
||||
fontWeight: FontWeight.bold,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.emoji_events, color: Colors.green.shade600, size: 20.w),
|
||||
SizedBox(width: 8.w),
|
||||
Flexible(
|
||||
child: Text(
|
||||
winnerName,
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Colors.green.shade700,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,16 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'animated_draw_wheel.dart';
|
||||
import 'alternative_draw_animations.dart';
|
||||
import 'particle_draw_animation.dart';
|
||||
|
||||
enum DrawAnimationType {
|
||||
spinningWheel,
|
||||
cardFlip,
|
||||
slotMachine,
|
||||
numberRoulette,
|
||||
particleSystem,
|
||||
}
|
||||
|
||||
class DrawAnimationSelector extends StatefulWidget {
|
||||
final List<Map<String, dynamic>> members;
|
||||
|
|
@ -35,28 +25,11 @@ class DrawAnimationSelector extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _DrawAnimationSelectorState extends State<DrawAnimationSelector> {
|
||||
DrawAnimationType _selectedAnimation = DrawAnimationType.cardFlip;
|
||||
bool _isDrawStarted = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// Auto-select best animation based on member count
|
||||
_selectBestAnimation();
|
||||
}
|
||||
|
||||
void _selectBestAnimation() {
|
||||
final memberCount = widget.members.length;
|
||||
|
||||
if (memberCount <= 8) {
|
||||
_selectedAnimation = DrawAnimationType.spinningWheel;
|
||||
} else if (memberCount <= 20) {
|
||||
_selectedAnimation = DrawAnimationType.cardFlip;
|
||||
} else if (memberCount <= 50) {
|
||||
_selectedAnimation = DrawAnimationType.slotMachine;
|
||||
} else {
|
||||
_selectedAnimation = DrawAnimationType.particleSystem;
|
||||
}
|
||||
}
|
||||
|
||||
void _startDraw() {
|
||||
|
|
@ -73,7 +46,7 @@ class _DrawAnimationSelectorState extends State<DrawAnimationSelector> {
|
|||
|
||||
Widget _buildAnimationSelector() {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(20.w),
|
||||
padding: EdgeInsets.all(24.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16.r),
|
||||
|
|
@ -86,33 +59,58 @@ class _DrawAnimationSelectorState extends State<DrawAnimationSelector> {
|
|||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'Choose Draw Animation',
|
||||
style: TextStyle(
|
||||
fontSize: 20.sp,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.grey.shade800,
|
||||
Container(
|
||||
width: 72.w,
|
||||
height: 72.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.purple.shade50,
|
||||
borderRadius: BorderRadius.circular(20.r),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.casino,
|
||||
color: Colors.purple.shade600,
|
||||
size: 36.w,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
|
||||
Text(
|
||||
'Members: ${widget.members.length}',
|
||||
'Slot Machine Draw',
|
||||
style: TextStyle(
|
||||
fontSize: 22.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Colors.grey.shade800,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
Text(
|
||||
'Our signature animation for dramatic, high-energy winner reveals.',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
color: Colors.grey.shade600,
|
||||
height: 1.4,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.purple.shade50,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Text(
|
||||
'Members in draw: ${widget.members.length}',
|
||||
style: TextStyle(
|
||||
fontSize: 13.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.purple.shade600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20.h),
|
||||
|
||||
// Animation Options
|
||||
...DrawAnimationType.values.map((type) => _buildAnimationOption(type)),
|
||||
|
||||
SizedBox(height: 24.h),
|
||||
|
||||
// Start Button
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
|
|
@ -131,7 +129,7 @@ class _DrawAnimationSelectorState extends State<DrawAnimationSelector> {
|
|||
Icon(Icons.play_arrow, size: 20.w),
|
||||
SizedBox(width: 8.w),
|
||||
Text(
|
||||
'Start ${_getAnimationName(_selectedAnimation)}',
|
||||
'Start Slot Machine',
|
||||
style: TextStyle(fontSize: 16.sp),
|
||||
),
|
||||
],
|
||||
|
|
@ -143,221 +141,6 @@ class _DrawAnimationSelectorState extends State<DrawAnimationSelector> {
|
|||
);
|
||||
}
|
||||
|
||||
Widget _buildAnimationOption(DrawAnimationType type) {
|
||||
final isSelected = _selectedAnimation == type;
|
||||
final isRecommended = _isRecommendedAnimation(type);
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: 12.h),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_selectedAnimation = type;
|
||||
});
|
||||
},
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? Colors.purple.shade50 : Colors.grey.shade50,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
border: Border.all(
|
||||
color: isSelected ? Colors.purple.shade300 : Colors.grey.shade300,
|
||||
width: 2.w,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 24.w,
|
||||
height: 24.w,
|
||||
margin: EdgeInsets.only(top: 2.h),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? Colors.purple.shade600 : Colors.grey.shade400,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: isSelected
|
||||
? Icon(Icons.check, color: Colors.white, size: 16.w)
|
||||
: null,
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
_getAnimationName(type),
|
||||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: isSelected ? Colors.purple.shade800 : Colors.grey.shade800,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
if (isRecommended) ...[
|
||||
SizedBox(width: 6.w),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 2.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.green.shade100,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Text(
|
||||
'Recommended',
|
||||
style: TextStyle(
|
||||
fontSize: 10.sp,
|
||||
color: Colors.green.shade700,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
SizedBox(height: 6.h),
|
||||
Text(
|
||||
_getAnimationDescription(type),
|
||||
style: TextStyle(
|
||||
fontSize: 12.sp,
|
||||
color: Colors.grey.shade600,
|
||||
height: 1.3,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
Icon(
|
||||
_getAnimationIcon(type),
|
||||
color: isSelected ? Colors.purple.shade600 : Colors.grey.shade400,
|
||||
size: 28.w,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool _isRecommendedAnimation(DrawAnimationType type) {
|
||||
final memberCount = widget.members.length;
|
||||
|
||||
switch (type) {
|
||||
case DrawAnimationType.spinningWheel:
|
||||
return memberCount <= 8;
|
||||
case DrawAnimationType.cardFlip:
|
||||
return memberCount > 8 && memberCount <= 20;
|
||||
case DrawAnimationType.slotMachine:
|
||||
return memberCount > 20 && memberCount <= 50;
|
||||
case DrawAnimationType.numberRoulette:
|
||||
return memberCount > 20 && memberCount <= 100;
|
||||
case DrawAnimationType.particleSystem:
|
||||
return memberCount > 50;
|
||||
}
|
||||
}
|
||||
|
||||
String _getAnimationName(DrawAnimationType type) {
|
||||
switch (type) {
|
||||
case DrawAnimationType.spinningWheel:
|
||||
return 'Spinning Wheel';
|
||||
case DrawAnimationType.cardFlip:
|
||||
return 'Card Flip';
|
||||
case DrawAnimationType.slotMachine:
|
||||
return 'Slot Machine';
|
||||
case DrawAnimationType.numberRoulette:
|
||||
return 'Number Roulette';
|
||||
case DrawAnimationType.particleSystem:
|
||||
return 'Particle System';
|
||||
}
|
||||
}
|
||||
|
||||
String _getAnimationDescription(DrawAnimationType type) {
|
||||
switch (type) {
|
||||
case DrawAnimationType.spinningWheel:
|
||||
return 'Classic spinning wheel - Best for small groups (≤8 members)';
|
||||
case DrawAnimationType.cardFlip:
|
||||
return 'Cards flipping rapidly - Great for medium groups (9-20 members)';
|
||||
case DrawAnimationType.slotMachine:
|
||||
return 'Slot machine style - Perfect for large groups (21-50 members)';
|
||||
case DrawAnimationType.numberRoulette:
|
||||
return 'Number roulette wheel - Good for very large groups (21-100 members)';
|
||||
case DrawAnimationType.particleSystem:
|
||||
return 'Particle effects - Best for massive groups (50+ members)';
|
||||
}
|
||||
}
|
||||
|
||||
IconData _getAnimationIcon(DrawAnimationType type) {
|
||||
switch (type) {
|
||||
case DrawAnimationType.spinningWheel:
|
||||
return Icons.casino;
|
||||
case DrawAnimationType.cardFlip:
|
||||
return Icons.style;
|
||||
case DrawAnimationType.slotMachine:
|
||||
return Icons.games;
|
||||
case DrawAnimationType.numberRoulette:
|
||||
return Icons.timeline;
|
||||
case DrawAnimationType.particleSystem:
|
||||
return Icons.auto_awesome;
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildSelectedAnimation() {
|
||||
switch (_selectedAnimation) {
|
||||
case DrawAnimationType.spinningWheel:
|
||||
return AnimatedDrawWheel(
|
||||
members: widget.members,
|
||||
onDrawComplete: widget.onDrawComplete,
|
||||
serverSeed: widget.serverSeed,
|
||||
clientSeed: widget.clientSeed,
|
||||
nonce: widget.nonce,
|
||||
);
|
||||
case DrawAnimationType.cardFlip:
|
||||
return CardFlipDrawAnimation(
|
||||
members: widget.members,
|
||||
onDrawComplete: widget.onDrawComplete,
|
||||
serverSeed: widget.serverSeed,
|
||||
clientSeed: widget.clientSeed,
|
||||
nonce: widget.nonce,
|
||||
animationDuration: widget.animationDuration,
|
||||
);
|
||||
case DrawAnimationType.slotMachine:
|
||||
return SlotMachineDrawAnimation(
|
||||
members: widget.members,
|
||||
onDrawComplete: widget.onDrawComplete,
|
||||
serverSeed: widget.serverSeed,
|
||||
clientSeed: widget.clientSeed,
|
||||
nonce: widget.nonce,
|
||||
animationDuration: widget.animationDuration,
|
||||
);
|
||||
case DrawAnimationType.numberRoulette:
|
||||
return NumberRouletteDrawAnimation(
|
||||
members: widget.members,
|
||||
onDrawComplete: widget.onDrawComplete,
|
||||
serverSeed: widget.serverSeed,
|
||||
clientSeed: widget.clientSeed,
|
||||
nonce: widget.nonce,
|
||||
animationDuration: widget.animationDuration,
|
||||
);
|
||||
case DrawAnimationType.particleSystem:
|
||||
return ParticleDrawAnimation(
|
||||
members: widget.members,
|
||||
onDrawComplete: widget.onDrawComplete,
|
||||
serverSeed: widget.serverSeed,
|
||||
clientSeed: widget.clientSeed,
|
||||
nonce: widget.nonce,
|
||||
animationDuration: widget.animationDuration,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
|
|
@ -366,7 +149,14 @@ class _DrawAnimationSelectorState extends State<DrawAnimationSelector> {
|
|||
children: [
|
||||
if (!_isDrawStarted) _buildAnimationSelector(),
|
||||
if (_isDrawStarted) ...[
|
||||
_buildSelectedAnimation(),
|
||||
SlotMachineDrawAnimation(
|
||||
members: widget.members,
|
||||
onDrawComplete: widget.onDrawComplete,
|
||||
serverSeed: widget.serverSeed,
|
||||
clientSeed: widget.clientSeed,
|
||||
nonce: widget.nonce,
|
||||
animationDuration: widget.animationDuration,
|
||||
),
|
||||
SizedBox(height: 20.h),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
|
|
@ -378,9 +168,20 @@ class _DrawAnimationSelectorState extends State<DrawAnimationSelector> {
|
|||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'Choose Different Animation',
|
||||
style: TextStyle(fontSize: 14.sp),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.refresh, size: 18.w, color: Colors.purple.shade600),
|
||||
SizedBox(width: 6.w),
|
||||
Text(
|
||||
'Spin Again',
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.purple.shade600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in New Issue