A customizable and interactive spin wheel component built with React and TypeScript. This component allows users to create engaging prize wheels for promotions, giveaways, games, or any interactive experience.
- 🎡 Smooth spinning animation with realistic physics
- 🎨 Fully customizable segments with colors, text, and values
- 🏆 Winner selection with visual and audio feedback
- 🎉 Confetti animation for winners
- 📱 Responsive design that works on all devices
- 🔧 Easy to configure and extend
- 🌐 Accessibility-friendly
npm install react-spin-wheel
# or
yarn add react-spin-wheelimport { SpinWheel } from 'react-spin-wheel';
function App() {
// Define your segments
const segments = [
{ text: "Prize 1", value: "prize-1", color: "#ff9f43" },
{ text: "$100", value: 100, color: "#2e86de" },
{ text: "Free Spin", value: "free-spin", color: "#10ac84" },
{ text: "50% Off", value: "50-off", color: "#ff6b6b" },
{ text: "Try Again", value: "try-again", color: "#8395a7" },
{ text: "$50", value: 50, color: "#6c5ce7" },
{ text: "25% Off", value: "25-off", color: "#fd79a8" },
{ text: "$25", value: 25, color: "#00b894" },
];
// Optional callback when spin ends
const handleSpinEnd = (value) => {
console.log(`User won: ${value}`);
};
return (
<div className="app">
<SpinWheel
segments={segments}
onSpinEnd={handleSpinEnd}
showConfetti={true}
/>
</div>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
segments |
Array<Segment> |
[] |
Array of segment objects with text, value, and color |
onSpinStart |
() => void |
undefined |
Callback function called when spin starts |
onSpinEnd |
(value: string | number) => void |
undefined |
Callback function called when spin ends with the winning value |
buttonText |
string |
"SPIN THE WHEEL" |
Text displayed on the spin button |
spinningText |
string |
"Spinning..." |
Text displayed while wheel is spinning |
size |
number |
300 |
Size of the wheel in pixels |
showConfetti |
boolean |
true |
Whether to show confetti animation for winners |
confettiConfig |
Object |
{} |
Configuration for confetti animation |
disabled |
boolean |
false |
Whether the wheel is disabled |
interface Segment {
text: string; // Text displayed on the segment
value: string | number; // Value associated with the segment
color: string; // Background color of the segment
}You can customize the appearance of the wheel by passing CSS classes or inline styles:
<SpinWheel
segments={segments}
className="my-custom-wheel"
wheelClassName="wheel-outer"
buttonClassName="spin-button"
centerClassName="wheel-center"
/>You can use the wheel as a controlled component:
function ControlledWheel() {
const [spinning, setSpinning] = useState(false);
const [winner, setWinner] = useState(null);
const handleSpinClick = () => {
setSpinning(true);
// You can pre-determine the winner
setWinner(null);
};
const handleSpinEnd = (value) => {
setSpinning(false);
setWinner(value);
};
return (
<SpinWheel
segments={segments}
spinning={spinning}
onSpinClick={handleSpinClick}
onSpinEnd={handleSpinEnd}
winner={winner}
/>
);
}The SpinWheel component uses CSS transforms and transitions to create a smooth spinning animation. The wheel is divided into segments using SVG clip paths, and the winner is determined by calculating where the wheel stops relative to the pointer.
The main mathematical logic:
- Each segment occupies
360 / segments.lengthdegrees of the wheel - The wheel rotates by a random amount plus the position needed to align the selected segment with the pointer
- The pointer is fixed at the top (0 degrees) position
- A cubic-bezier transition gives the wheel a realistic spinning effect
Contributions are welcome! Please feel free to submit a Pull Request.
-
Clone the repository
git clone https://github.com/yourusername/react-spin-wheel.git cd react-spin-wheel -
Install dependencies
npm install # or yarn -
Start the development server
npm run dev # or yarn dev
- Follow the existing code style
- Write tests for new features
- Update documentation for any changes
- Make sure all tests pass before submitting a PR
- On some older browsers, the spinning animation might not be smooth
- [Add any known issues here]
- Add sound effects
- Support for custom segment shapes
- Add more animation options
- Improve accessibility features
- Create React Native version
MIT © [Solahudeen Abdulrahmon]
- React - UI library
- TypeScript - Type checking
- react-confetti - Confetti animation