spinning_wheel_package 0.0.1
spinning_wheel_package: ^0.0.1 copied to clipboard
A highly customizable Flutter package for creating a spinning wheel widget for games, raffles, and decision-making.
🌀 Spinning Wheel Package #
A customizable Flutter package for creating visually appealing and interactive spinning wheels — perfect for games, quizzes, random selection tools, and more.
This package supports rich styling, section-specific colors, gradient customization, sound effects, and custom pointer images.
✨ Features #
- 🎨 Customizable spinning wheel
- 🌈 Gradient color support per section
- 🔊 Sound playback on spin
- 🪞 Custom pointer image
- ⚙️ Silver and Wooden rim styles
- 🧩 Spin start and result callbacks
🚀 Getting Started #
Add the package to your `pubspec.yaml`:
Then, import it:
import 'package:spinning_wheel_package/spinning_wheel_package.dart';
📦 Assets Setup #
flutter: assets:
- assets/audios/spin.mp3
- assets/images/pointer.png
🎨 Customization Properties #
| Property | Type | Description |
|---|---|---|
sections |
List<WheelItem> |
✅ Required. The list of items to display on the wheel. |
spinDuration |
double |
The duration of the spin animation in seconds. |
onSpinStart |
Function()? |
Callback when the wheel starts spinning — great for playing sound effects. |
onSpinEnd |
Function(int)? |
Callback when the wheel stops, returning the index of the winning slice. |
wheelWidth |
double |
The width of the spinning wheel. |
wheelHeight |
double |
The height of the spinning wheel. |
showSpinButton |
bool |
If true, displays the default spin button below the wheel. |
spinButtonChild |
Widget |
A custom widget to use for the spin button's content. |
spinButtonStyle |
ButtonStyle? |
Custom styling for the default spin button. |
rimType |
WheelRimType |
Sets the wheel's rim style: normal, christmas, silver, etc. |
wheelRimColor |
Color |
The color of the rim when rimType is normal. |
wheelRimWidth |
double |
The width (thickness) of the wheel's outer rim. |
customRimWidth |
double |
The width of the image overlay rim (e.g., for silver or wood). |
customRimHeight |
double |
The height of the image overlay rim. |
pegColor |
Color |
The color of the pegs between each wheel section. |
pegSize |
double |
The radius of the pegs. |
pegPosition |
PegPosition |
Sets the position of the pegs: start or center of each slice. |
showChristmasCap |
bool |
If true, shows a Santa cap when rimType is christmas. |
positionChristmasCapVertical |
double |
The vertical position of the Christmas cap overlay. |
positionChristmasCapHorizontal |
double |
The horizontal position of the Christmas cap overlay. |
textOrientation |
WheelTextOrientation |
Sets text direction: horizontal or vertical inside each section. |
itemTextColor |
Color |
The color of the text inside each wheel section. |
itemFontSize |
double |
The font size for the text in each section. |
itemFontWeight |
FontWeight |
The font weight for the text in each section. |
itemFontFamily |
String |
The font family for the text in each section. |
textMargin |
double |
A multiplier for how far from the center the text is placed (e.g., 0.5). |
useCustomPointer |
bool |
If true, enables using a custom image for the pointer. |
pointerImagePath |
String? |
Path to the pointer image asset. Required if useCustomPointer is true. |
pointerType |
PointerType |
Type of default pointer shape: triangle or cone. |
pointerColor |
Color |
The color of the default painted pointer. |
pointerPinColor |
Color |
The color of the small pin on the cone pointer. |
positionCustomPointerVertical |
double |
The vertical position of the custom image pointer. |
positionCustomPointerHorizontal |
double |
The horizontal position of the custom image pointer. |
positionDefaultPointerVertical |
double |
The vertical position of the default painted pointer. |
positionDefaultPointerHorizontal |
double |
The horizontal position of the default painted pointer. |
centerHubWidth |
double |
The width of the central hub of the wheel. |
centerHubHeight |
double |
The height of the central hub of the wheel. |
centerHubColor |
Color |
The background color of the central hub. |
centerHubEdgeColor |
Color |
The border color of the central hub. |
centerHubText |
String |
The text to display inside the central hub. |
centerHubTextSize |
double |
The font size for the hub text. |
centerHubTextColor |
Color |
The color for the hub text. |
showWheelStand |
bool |
If true, displays the stand below the wheel. |
standColor |
Color |
The color of the wheel stand. |
standOffset |
double |
Controls the vertical alignment of the stand. |
showWheelShadow |
bool |
If true, displays a shadow effect around the wheel rim. |
wheelShadowColor |
Color |
The color of the wheel's outer shadow. |
🛠️ Usage Example #
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
import 'package:spinning_wheel_package/spinning_wheel_package.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Spin Package Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(title: 'Wheel Spin Package'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final AudioPlayer _audioPlayer = AudioPlayer();
bool _isSoundLoading = false;
String _spinResult = "Spin the wheel!";
final List<WheelItem> _sections = [
WheelItem(text: "Music", gradientColors: [Color(0XFFF2C403), Color(0XFF8C7102)],),
WheelItem(text: "Art & Books", gradientColors: [Color(0XFFA70002), Color(0XFF410001)],),
WheelItem(text: "Other Sports", gradientColors: [Color(0XFFCE5097), Color(0XFF68284C)]),
WheelItem(text: "Nutrition", gradientColors: [Color(0XFF0783B4), Color(0XFF03394E)]),
WheelItem(text: "Entertainment", gradientColors: [Color(0XFF77C601), Color(0XFF3A6000)]),
WheelItem(text: "Current Affairs", gradientColors: [Color(0XFF9301B8), Color(0XFF420052)]),
];
@override
void dispose() {
_audioPlayer.dispose();
super.dispose();
}
///You can add a sound to the wheel by adding an audio file in the assets folder with any audio package of your choice
Future<void> _playSound() async {
// If a sound is already being prepared, do nothing
if (_isSoundLoading) return;
// Set the flag to block other calls
_isSoundLoading = true;
try {
// setAsset implicitly stops any previous sound
await _audioPlayer.setAsset('assets/audios/spin.mp3');
// Rewind to the beginning to ensure it plays every time
await _audioPlayer.seek(Duration.zero);
_audioPlayer.play();
} catch (e) {
print("Error playing sound: $e");
} finally {
// Always release the flag when done
_isSoundLoading = false;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
_spinResult,
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SpinningWheel(
sections: _sections,
onSpinStart: (){
_playSound();
},
onSpinEnd: (index) {
setState(() {
_spinResult = "Result: ${_sections[index].text}";
});
},
rimType: WheelRimType.silver,
standOffset: 0,
centerHubWidth: 50,
centerHubHeight: 50,
centerHubText: 'SPIN',
useCustomPointer: true,
pointerImagePath: 'assets/images/pointer.png',
)
],
),
),
);
}
}