vue3-spin-wheel
v1.0.1
Published
A customizable spin wheel component for Vue 3
Maintainers
Readme
vue3-spin-wheel-sample
A customizable spin wheel component for Vue 3.
Installation
npm install vue3-spin-wheelUsage
Basic Usage
<template>
<SpinWheel
:items="items"
:size="600"
@spin-start="handleSpinStart"
@spin-end="handleSpinEnd"
/>
</template>
<script setup>
import { SpinWheel } from 'vue3-spin-wheel'
import 'vue3-spin-wheel/dist/style.css'
const items = [
{ id: 1, label: 'Item 1', color: '#FF6B6B' },
{ id: 2, label: 'Item 2', color: '#4ECDC4' },
// ... more items
]
const handleSpinStart = () => {
console.log('Spin started!')
}
const handleSpinEnd = (item, index) => {
console.log('Selected:', item, index)
}
</script>With API Integration
<template>
<SpinWheel
ref="spinWheel"
:items="items"
:size="600"
@spin-start="handleSpinStart"
@spin-end="handleSpinEnd"
/>
</template>
<script setup>
import { ref } from 'vue'
import { SpinWheel } from 'vue3-spin-wheel'
import 'vue3-spin-wheel/dist/style.css'
const spinWheel = ref(null)
const items = [
// {
// id: id,
// label: tên trên slice,
// color: màu background trên slice (ko truyền sẽ lấy màu default như design ban đầu),
// textColor: màu text trên slice (ko truyền sẽ lấy màu default như design ban đầu),
// value: value,
// image: hình,
// imageSize: size hình
// },
{
id: 1,
label: 'Green',
color: '#E8D5FF',
textColor: '',
value: 'hoa-hiep',
image: 'https://picsum.photos/200/300',
imageSize: 80
},
{
id: 2,
label: 'Ron',
color: '#D4A574',
textColor: '#8B4513',
value: 'bach-bao',
image: 'https://picsum.photos/seed/picsum/200/300',
imageSize: 80
},
{
id: 3,
label: 'Alex',
color: '#B8E6FF',
textColor: '#0066CC',
value: 'tinh-long',
image: 'https://picsum.photos/200/300?grayscale',
imageSize: 80
},
]
const handleSpinStart = async () => {
// Call your API
const response = await fetch('/api/spin')
const data = await response.json()
// Set the result when API returns
spinWheel.value.setSpinResult(data.itemId)
}
const handleSpinEnd = (item, index) => {
console.log('Selected:', item, index)
}
</script>Props
items(Array, required): Array of items to display on the wheelsize(Number, default: 400): Size of the wheel in pixels
Events
@spin-start: Emitted when spin starts@spin-end: Emitted when spin ends with selected item and index
Methods
spin(): Start spinningsetSpinResult(itemId): Set the result from API/server
License
Inluce in page with congrats dialog (sample)
<div class="flex flex-col items-center justify-center w-full max-w-[600px] aspect-square">
<SpinWheel
ref="spinWheel"
:items="nameItems"
spinButtonText="RUN"
@spin-start="handleSpinStart"
@spin-end="handleFoodSelected"
/>
</div>
<!-- Congratulations Modal Overlay -->
<Transition name="modal">
<div
v-if="foodSelected && !isSpinning"
class="fixed inset-0 z-50 flex items-center justify-center p-4"
@click.self="closeCongrats"
>
<!-- Backdrop -->
<div class="absolute inset-0 bg-black bg-opacity-50"></div>
<!-- Confetti Container -->
<div class="confetti-container absolute inset-0 pointer-events-none overflow-hidden">
<div
v-for="i in 50"
:key="i"
class="confetti"
:style="getConfettiStyle(i)"
></div>
</div>
<!-- Modal Dialog -->
<div class="modal-dialog relative bg-white rounded-lg shadow-2xl w-full overflow-hidden max-w-[1000px] sm:mx-4">
<!-- Yellow Header -->
<div class="bg-yellow-400 px-4 py-3 sm:px-6 sm:py-4 flex items-center justify-between">
<h2 class="text-lg sm:text-xl font-bold text-black">The prize is...</h2>
<button
@click="closeCongrats"
class="text-black hover:text-gray-700 text-xl sm:text-2xl font-bold leading-none"
aria-label="Close"
>
×
</button>
</div>
<!-- Content -->
<div class="px-4 py-6 sm:px-6 sm:py-8 text-center">
<h3 class="text-2xl sm:text-3xl md:text-4xl font-bold text-black mb-4">
{{ foodSelected.label }}
</h3>
<div v-if="foodSelected.image" class="mt-2">
<img
:src="foodSelected.image"
:alt="foodSelected.label"
class="w-24 h-24 sm:w-32 sm:h-32 rounded-full mx-auto object-cover border-4 border-gray-200"
/>
</div>
</div>
<!-- Action Buttons -->
<div class="px-4 py-3 sm:px-6 sm:py-4 bg-gray-50 flex justify-end gap-3">
<button
@click="closeCongrats"
class="px-4 py-2 sm:px-6 sm:py-2 bg-white border border-gray-300 text-black rounded hover:bg-gray-50 transition-colors text-sm sm:text-base"
>
Close
</button>
</div>
</div>
</div>
</Transition>
</div>