Spinning Wheel
sidcn/spinning-wheelFreeComponent
A lottery-like spinning wheel component
Live preview
live · rendered by the registry
Rendered by sidcn on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.siddhesh.cc/r/spinning-wheel.jsonSource
1"use client";23import { useState, useRef } from "react";45import { Button } from "@/registry/new-york/components/button";67export type Reward =8 | {9 reward: string;10 weight?: number;11 bgColor: string;12 textColor: string;13 }14 | {15 reward: string;16 weight?: number;17 };1819export function SpinningWheel({20 rewardDetails,21 disabled = false,22 radius = 200,23 setReward,24}: {25 rewardDetails: Reward[];26 disabled?: boolean;27 radius?: number;28 setReward?(reward: string | null): void;29}) {30 // Seperate all the properties31 const rewards = rewardDetails.map((reward) => reward.reward);32 const bgColors = rewardDetails.every((reward) => "bgColor" in reward)33 ? rewardDetails.map((reward) => reward.bgColor)34 : ["#FFF", "#000"];3536 const textColors = rewardDetails.every((reward) => "textColor" in reward)37 ? rewardDetails.map((reward) => reward.textColor)38 : ["#000", "#FFF"];39 let weights = rewardDetails.map((reward) => reward?.weight || 1);40 if (!weights) {41 weights = new Array(rewards.length).fill(1);42 }4344 // State variables45 const [isSpinning, setIsSpinning] = useState(false);46 const [rotation, setRotation] = useState(0);47 const [finalRotation, setFinalRotation] = useState(0);48 const wheelRef = useRef(null);4950 // internal calculation variables51 const totalWeights = weights.reduce((a, b) => a + b, 0);52 const segmentAngle = 360 / rewards.length;53 const calcSegmentAngle = 360 / totalWeights;54 const calcRewards = rewards55 .map((reward, index) => new Array(weights[index]).fill(reward))56 .flat();5758 const spinWheel = () => {59 if (isSpinning) return;6061 setIsSpinning(true);62 if (setReward) setReward(null);6364 // Determine a random position to stop (between 2 and 5 full rotations + random segment)65 const minRotations = 5;66 const maxRotations = 7;67 const randomRotations =68 minRotations + Math.random() * (maxRotations - minRotations);69 const randomRewardIndex = Math.floor(Math.random() * totalWeights);70 const randomAngle =71 segmentAngle * rewards.indexOf(calcRewards[randomRewardIndex]);7273 const totalRotation = randomRotations * 360 + randomAngle;7475 // Determine the final rotation76 const newFinalRotation = rotation + totalRotation;77 setFinalRotation(newFinalRotation);7879 // Determine the selected reward based on where the wheel stops80// … truncated
What it pulls in
Other registry items
Files it writes
More from sidcn
All 14 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Badgebadge | sidcn | Components | Free | 3 deps | |
| Buttonbutton | sidcn | Components | Free | 2 deps | |
| Data Tabledata-table | sidcn | Components | Free | 2 deps | |
| Date Inputdate-input | sidcn | Components | Free | 1 dep | |
| Date Time Inputdate-time-input | sidcn | Components | Free | 2 deps | |
| Iconsicons | sidcn | Components | Free | no deps | |
| Package Manager Commandpackage-manager-command | sidcn | Components | Free | no deps | |
| Sidebarsidebar | sidcn | Components | Free | 3 deps |
