Hlo

import React, { useState, useRef, useEffect } from 'react'; import { Trash2, Plus, Shuffle, Trophy, Volume2, VolumeX } from 'lucide-react'; import confetti from 'canvas-confetti'; const UltimatePickerWheel = () => { // State for the items on the wheel const [items, setItems] = useState([ { id: 1, text: 'Pizza', color: '#FF6B6B' }, { id: 2, text: 'Burger', color: '#4ECDC4' }, { id: 3, text: 'Sushi', color: '#45B7D1' }, { id: 4, text: 'Salad', color: '#FFA07A' }, { id: 5, text: 'Tacos', color: '#98D8C8' }, ]); const [inputValue, setInputValue] = useState(''); const [isSpinning, setIsSpinning] = useState(false); const [winner, setWinner] = useState(null); const [rotation, setRotation] = useState(0); const [soundEnabled, setSoundEnabled] = useState(true); // Sound Refs (You can replace these URLs with your own hosted files) const spinSound = useRef(new Audio('https://assets.mixkit.co/sfx/preview/mixkit-drum-roll-566.mp3')); const winSound = useRef(new Audio('https://assets.mixkit.co/sfx/preview/mixkit-winning-chimes-2015.mp3')); // Colors to cycle through when adding new items const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#F7DC6F', '#BB8FCE', '#A3E4D7']; const handleAddItem = (e) => { e.preventDefault(); if (!inputValue.trim()) return; const newItem = { id: Date.now(), text: inputValue, color: colors[items.length % colors.length] }; setItems([...items, newItem]); setInputValue(''); }; const handleRemoveItem = (id) => { setItems(items.filter(item => item.id !== id)); }; const triggerConfetti = () => { const duration = 3000; const end = Date.now() + duration; (function frame() { confetti({ particleCount: 5, angle: 60, spread: 55, origin: { x: 0 }, colors: colors }); confetti({ particleCount: 5, angle: 120, spread: 55, origin: { x: 1 }, colors: colors }); if (Date.now() < end) { requestAnimationFrame(frame); } }()); }; const spinWheel = () => { if (isSpinning || items.length < 2) return; setIsSpinning(true); setWinner(null); if (soundEnabled) { spinSound.current.currentTime = 0; spinSound.current.play().catch(() => {}); } // Calculate a new random rotation // Min 5 spins (1800 deg) + random variance const newRotation = rotation + 1800 + Math.floor(Math.random() * 360); setRotation(newRotation); // Calculate winner index // The pointer is usually at the top (270deg) or right (0deg). // Assuming CSS rotates clockwise and pointer is at the right (0deg): // We need to find where the wheel stops. setTimeout(() => { const actualDeg = newRotation % 360; const segmentSize = 360 / items.length; // Calculate index based on pointer position (Right side pointer logic) // Note: CSS conic gradients start at 12 o'clock usually, adjustments needed based on CSS const winningIndex = Math.floor((360 - actualDeg) / segmentSize) % items.length; const winningItem = items[winningIndex]; setWinner(winningItem); setIsSpinning(false); if (soundEnabled) { spinSound.current.pause(); winSound.current.play().catch(() => {}); } triggerConfetti(); }, 4000); // Duration matches CSS transition }; // Create Conic Gradient for the wheel const wheelGradient = `conic-gradient( ${items.map((item, index) => { const start = (index / items.length) * 100; const end = ((index + 1) / items.length) * 100; return `${item.color} ${start}% ${end}%`; }).join(', ')} )`; return (
{/* Header / Ad Space Placeholder */}

Pick-A-Winner

The Ultimate Random Decision Maker

{/* LEFT SIDE: The Wheel */}
{/* Pointer */}
{/* The Wheel */}
{/* Text Labels inside Wheel */} {items.map((item, index) => { const angle = (360 / items.length) * index + (360 / items.length) / 2; return (
{item.text}
); })}
{/* Center Cap */}
{/* RIGHT SIDE: Controls */}

Inputs

setInputValue(e.target.value)} placeholder="Add an option..." className="flex-1 bg-slate-700 border border-slate-600 rounded-lg px-4 py-2 focus:outline-none focus:border-pink-500 text-white" maxLength={25} />
{items.map((item) => (
{item.text}
))}
{items.length} options available
{/* Winner Modal */} {winner && !isSpinning && (

We have a winner!

{winner.text}
)} {/* SEO Text / Explanation (Vital for the business model) */}

Use this wheel to randomly pick a winner, decide what to eat, or choose a name.

); }; export default UltimatePickerWheel;

Comments