gluecksrad
v1.1.1
Published
A beautiful, customizable lottery wheel component for React applications
Maintainers
Readme
Gluecksrad
A highly customizable, reusable wheel component with advanced rotation animation capabilities and external control.
Demo
Check out the live demo to see the wheel in action!
Features
- 🎯 External Control: Public
spin()function for programmatic control - ⚙️ Configurable Animation: Duration, rotations, and easing customization
- 📡 Rich Callbacks: onSpinStart, onSpinning, onSpinComplete events
- 🔄 State Management: Maintains rotation state across multiple spins
- 🎨 Fully Customizable: Colors, sizes, and visual elements
- 📱 TypeScript Support: Complete type safety and IntelliSense
- 🎪 Smooth Animations: Powered by Anime.js
Installation
npm install gluecksradBasic Usage
import React, { useRef } from 'react';
import { Wheel, type WheelRef } from 'gluecksrad';
const segments = [
{ id: 1, name: '$1000', color: '#6366F1' },
{ id: 2, name: '$500', color: '#8B5CF6' },
{ id: 3, name: '$250', color: '#EC4899' },
{ id: 4, name: '$100', color: '#EF4444' },
];
function BasicExample() {
const wheelRef = useRef<WheelRef>(null);
const handleSpin = async () => {
if (wheelRef.current) {
const result = await wheelRef.current.spin();
console.log('Winner:', result.winningSegment);
}
};
return (
<div>
<Wheel
ref={wheelRef}
segments={segments}
onSpinComplete={(angle, winner) => {
console.log('Spin complete!', winner);
}}
/>
<button onClick={handleSpin}>Spin Wheel</button>
</div>
);
}Advanced Usage
import React, { useRef, useState } from 'react';
import { Wheel, type WheelRef, type WheelRotationParams } from 'gluecksrad';
const segments = [
{ id: 1, name: '$1000', color: '#6366F1' },
{ id: 2, name: '$500', color: '#8B5CF6' },
{ id: 3, name: '$250', color: '#EC4899' },
{ id: 4, name: '$100', color: '#EF4444' },
];
function AdvancedExample() {
const wheelRef = useRef<WheelRef>(null);
const [currentAngle, setCurrentAngle] = useState(0);
const [isSpinning, setIsSpinning] = useState(false);
const customSpin = async () => {
if (!wheelRef.current) return;
const params: WheelRotationParams = {
duration: 5, // 5 seconds
rotations: 4, // 4 full rotations
easing: 'easeOutElastic(1, .8)',
finalAngle: 45 // Stop at 45 degrees
};
const result = await wheelRef.current.spin(params);
console.log('Custom spin result:', result);
};
const resetWheel = () => {
wheelRef.current?.reset();
};
const setSpecificAngle = () => {
wheelRef.current?.setAngle(90); // Set to 90 degrees
};
return (
<div>
<Wheel
ref={wheelRef}
segments={segments}
size={500}
defaultRotationParams={{
duration: 3,
rotations: 2,
easing: 'easeOutCubic'
}}
onSpinStart={() => {
console.log('Spin started!');
setIsSpinning(true);
}}
onSpinning={(angle) => {
setCurrentAngle(angle);
}}
onSpinComplete={(angle, winner) => {
console.log('Spin completed!', winner);
setIsSpinning(false);
}}
/>
<div>
<p>Current Angle: {currentAngle.toFixed(2)}°</p>
<p>Is Spinning: {isSpinning ? 'Yes' : 'No'}</p>
</div>
<div>
<button onClick={customSpin}>Custom Spin</button>
<button onClick={resetWheel}>Reset</button>
<button onClick={setSpecificAngle}>Set to 90°</button>
</div>
</div>
);
}API Reference
WheelRef Methods
interface WheelRef {
// Spin the wheel with optional parameters
spin(params?: WheelRotationParams): Promise<{
finalAngle: number;
winningSegment?: WheelSegment;
}>;
// Get current rotation angle
getCurrentAngle(): number;
// Check if wheel is currently spinning
isSpinning(): boolean;
// Reset wheel to initial position
reset(): void;
// Set wheel to specific angle (only when not spinning)
setAngle(angle: number): void;
}WheelRotationParams
interface WheelRotationParams {
duration?: number; // Duration in seconds (default: 4)
rotations?: number; // Number of full rotations (default: 3-6 random)
easing?: string; // Anime.js easing function (default: 'easeOutCubic')
finalAngle?: number; // Specific final angle (default: random)
}Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| segments | WheelSegment[] | Required | Array of wheel segments |
| size | number | 400 | Wheel diameter in pixels |
| className | string | '' | Additional CSS classes |
| style | React.CSSProperties | {} | Inline styles |
| centerCircleColor | string | 'rgba(255,255,255,0.2)' | Center circle color |
| pointerColor | string | '#FFFFFF' | Pointer color |
| textColor | string | '#FFFFFF' | Text color |
| borderColor | string | 'rgba(255,255,255,0.15)' | Border color |
| showBorder | boolean | true | Show segment borders |
| showPointer | boolean | true | Show pointer |
| defaultRotationParams | WheelRotationParams | {} | Default rotation settings |
| disabled | boolean | false | Disable wheel spinning |
| initialAngle | number | 0 | Initial rotation angle |
Callbacks
| Callback | Type | Description |
|----------|------|-------------|
| onSpinStart | () => void | Called when spin begins |
| onSpinning | (currentAngle: number) => void | Called during rotation |
| onSpinComplete | (finalAngle: number, winningSegment?: WheelSegment) => void | Called when spin ends |
Animation Easing Options
'linear''easeInQuad','easeOutQuad','easeInOutQuad''easeInCubic','easeOutCubic','easeInOutCubic''easeInElastic','easeOutElastic','easeInOutElastic'- Custom cubic-bezier functions
Examples
Programmatic Control
// Spin with custom parameters
await wheelRef.current?.spin({
duration: 6,
rotations: 5,
easing: 'easeOutBounce'
});
// Get current state
const angle = wheelRef.current?.getCurrentAngle();
const spinning = wheelRef.current?.isSpinning();Event Handling
<Wheel
segments={segments}
onSpinStart={() => console.log('Started!')}
onSpinning={(angle) => console.log(`Angle: ${angle}`)}
onSpinComplete={(angle, winner) => console.log('Winner:', winner)}
/>License
MIT License
