Wheel of Fortune
Flagship spin-to-win component with physics-based animation and fairness UX.
10025.6%
20020.5%
50012.8%
10007.7%
JACKPOT2.6%
5030.8%
Odds displayed before each spin. Results are randomly determined.
Features
- Physics-based animation — Realistic deceleration with customizable easing
- Weighted segments — Configure win probability per segment
- Fairness UX — Optional probability display before spin
- Accessible — Screen reader announcements, keyboard control
- Reduced motion — Respects
prefers-reduced-motion - Mobile optimized — Touch-friendly, responsive sizing
Usage
vue
<script setup>
import { FkWheel } from '@fortune-kit/components'
const segments = [
{ id: '1', label: '100', value: 100, weight: 10, color: '#22c55e' },
{ id: '2', label: '500', value: 500, weight: 5, color: '#3b82f6' },
{ id: '3', label: 'JACKPOT', value: 5000, weight: 1, color: '#ef4444' }
]
function handleResult(segment) {
console.log('Winner:', segment)
}
</script>
<template>
<FkWheel
:segments="segments"
:size="320"
show-probability
@spin-end="handleResult"
/>
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
segments | WheelSegment[] | Required | Array of wheel segments |
size | number | 320 | Wheel diameter in pixels |
spinDuration | number | 4000 | Spin animation duration (ms) |
disabled | boolean | false | Disable spinning |
showProbability | boolean | false | Show odds before spin |
reduceMotion | boolean | false | Force reduced motion mode |
mode | 'local' | 'server' | 'local' | Result determination mode |
Segment Type
ts
interface WheelSegment {
id: string
label: string
value: number | string
weight?: number // Higher = more likely (default: 1)
color?: string // Segment color
}Events
| Event | Payload | Description |
|---|---|---|
spinStart | — | Emitted when spin begins |
spinEnd | WheelSegment | Emitted with winning segment |
click | — | Emitted when spin button clicked |
Accessibility
- Keyboard:
SpaceorEnterto spin - Screen reader announces result after spin
- Respects
prefers-reduced-motionsystem setting - High contrast segment colors
Fairness UX
Enable show-probability to display odds before each spin. This builds trust by being transparent about win chances.
vue
<FkWheel :segments="segments" show-probability />Each segment shows its percentage based on weight calculation.
Server Mode
For production use, you often want the server to determine the result for security and fairness. Use mode="server" to spin the wheel indefinitely until you provide a result from your backend.
vue
<script setup>
import { ref } from 'vue'
import { FkWheel } from '@fortune-kit/components'
const wheelRef = ref()
const segments = [
{ id: 'prize-100', label: '100', value: 100 },
{ id: 'prize-500', label: '500', value: 500 },
{ id: 'jackpot', label: 'JACKPOT', value: 5000 }
]
async function handleSpinStart() {
// Wheel starts spinning, fetch result from server
const response = await fetch('/api/spin')
const { segmentId } = await response.json()
// Set the result - wheel will slow down and stop on this segment
wheelRef.value.setResult(segmentId)
}
function handleSpinEnd(segment) {
console.log('Winner:', segment)
}
</script>
<template>
<FkWheel
ref="wheelRef"
:segments="segments"
mode="server"
@spin-start="handleSpinStart"
@spin-end="handleSpinEnd"
/>
</template>Exposed Methods (Server Mode)
Access these via template ref:
| Method | Description |
|---|---|
setResult(segmentId: string) | Stop wheel on specified segment |
isWaitingForResult | ComputedRef<boolean> - true while waiting for result |
reset() | Reset wheel to initial state |
How It Works
- User clicks Spin - wheel starts continuous rotation
@spin-startevent fires - you call your API- Wheel displays "Waiting..." and keeps spinning
- When API responds, call
wheelRef.value.setResult('segment-id') - Wheel decelerates and stops on the target segment
@spin-endevent fires with the winning segment