尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A dramatic spinning wheel and random name picker for draft orders, giveaways, party games, and any moment that deserves a little spectacle.
SpinPage turns a simple random picker into a casino-style show on a dark stage: a brass wheel with marquee bulbs, fanfare, confetti, an undoable draft board, autospin, plot twists, and a second-chance wheel where no one is ever completely safe. It is a static site with no dependencies and no build step.
Made by Gunnþór Karl Rafnsson.
The wheel, SPIN and the live numbers are on screen together and the page never scrolls, from a 320px phone to a 4K monitor:
The scoreboard always shows the next pick, how many are left on the wheel, the latest pick and the spin count (with illegal spins). The status line under it says what the wheel is doing: ready (with each name's real odds), spinning (with the name under the pointer), a power-up and what it did to the odds, a stunt, the result.
Spinning wheel picker drawn at your screen's real resolution, with rim pegs you can see and hear and a flapper pointer that kicks on every peg.
Grab-to-spin: drag the wheel with a mouse or finger and let go. Your flick sets the speed, the lap count and the drama — never the winner, which is drawn after your hand leaves the wheel. Only the wheel itself is grabbable; a second finger or a resting finger does nothing.
Pop-off: a violent enough hand-flick can rip the wheel off its hub. It either ricochets around the screen or drops to the floor and rolls away, then hops back onto the hub to finish the very same spin. Half the time it stays on instead and spins so fast it strobes like a car wheel on film: it seems to stop, crawl backwards and surge forwards again while the pegs scream, then catches up with the real wheel exactly.
The winner's moment: the winning slice lights up, the rest dim, and a nameplate rises over the wheel with the pick number. Nothing blacks out the board or the scoreboard.
Draft board: every seat from first to last — the picks so far, the one on the clock, the empty ones still to come — with the winner cut drawn where it falls.
Autospin for hands-free draft generation. Auto can be switched on or off at any moment — mid-spin, mid-event, even from inside a PANIC game — and takes over from the next pick. The phone stays awake while it runs.
Undo reverses whatever happened last: a pick, a stolen seat or a whole PANIC game. Restore all, Delete picks and Reset table act at once and offer an Undo for ten seconds.
Paste a list: a column copied from a spreadsheet or a notes app becomes one player per line.
Chaos: one slider in Settings, from Tame through Normal to Mayhem, sets how often every twist below turns up. At any level the odds lean away from repeats: a twist that has just happened gets rarer for a while (the more often, the rarer), the PANIC wedge visibly shrinks each time it hits (further the more seats it cost), and once a draft has taken more spins than it has names, the twists that undo picks ease off. Nothing is forced and nothing switches off; the odds only lean. A draft back to nobody seated starts with a clean slate. At Normal a twenty-name draft takes about 30 spins and almost never more than 45, where it used to average 58 and could run past 300.
Wind-back: the wheel runs an ordinary spin, creeps to a stop on a slice — and then gets dragged backwards, held, and thrown forward again onto the real winner.
The Gremlin: as the wheel crawls through its last degree, something climbs onto the rim, creeps it round by hand, fakes the stop, looks innocently away — and grabs it again. A slow burn from ten seconds to a minute and a half; rare at a full table, up to about one spin in four with three names left. Until he has turned up once on a device he is a little likelier (10% of spins at a full table, 40% near the end, against 5% and 30% after), so a new table gets to meet him.
Power-up slices (Hot Seat, Cursed, Wildcard) swell or shrink a slice before a spin and genuinely shift the odds; the status line spells out the change (14% → 33%) for the whole spin, on every screen.
PANIC slice that throws every drafted player into one of two games, on a coin flip, where only the majority keep their seats:
Both run at a fixed 60 steps a second, so a 120Hz phone plays the same game as a 60Hz monitor, and both can be skipped to the result (Skip, or Esc). Skip ignores presses for the first second, and focus is not put on it, so the Space, Enter or click that spun the wheel can't skip the game as it opens.
Illegal spin moments with a stamped invalid result and retry.
No One Is Safe: after a pick, the wheel can turn over to show the drafted seats under a red light and spin once to steal one. It plays on the stage, so the scoreboard, the board (seats at risk, then the one lost) and the console stay up; Esc skips to the result (SPIN doesn't: it's the button everyone presses to spin again), and Auto stays live.
Sound: all synthesized, nothing downloaded: peg clicks that get their body back (and a flapper bounce) as the wheel slows, a reveal as the name comes up (the wheel locking, a swoosh with the nameplate, then a ta-DAA for a winner or a lighter ding-ding for a later pick), a marimba-and-brass fanfare with a coin shower when a PANIC game is decided, a bugle call, hoofbeats and a bell for every safe finisher in the race, lever, reel whirr, clunks, 7 dings, a drum roll, the sad trombone and a jackpot at the slots, a sound for each power-up, a buzzer on an illegal spin, and a pop for every name added. The mute is remembered.
Calm effects: follows your system's reduce-motion setting (or the switch in Settings) — no confetti, fire, shaking or flashing, a three-second spin to the same result, and the PANIC games at double speed.
Accessible: every result is announced to screen readers, everything works from the keyboard (Space spins), dialogs and sheets manage focus, and phone targets are at least 44px.
Local persistence through localStorage, so your table survives refreshes — including in the middle of an event.
Zero runtime dependencies.
git clone https://github.com/gunnthor/SpinPage.git
cd SpinPage
Open index.html in your browser — it works straight from disk. Or serve the folder:
python -m http.server 8000
Settings has a Chaos slider for how often the twists turn up, and every twist as a switch: wind-back, gremlin, pop-off, power-ups, the Panic slice and No One Is Safe, plus winner display timing, sound, calm effects and the Rigged house rule. Turn them all off and you have a plain, fast wheel spinner.
Is it fair? Every spin draws its winner, weighted by slice size, before the wheel has moved a degree. Power-ups change slice sizes and the real odds, and say so. Hand flicks, wind-backs, the gremlin and pop-offs only change the route the wheel takes to get there. The one exception is Rigged, which you have to switch on yourself and which switches itself off when you reload.
SpinPage/
├── index.html # Markup, SEO metadata and the About/FAQ copy
├── css/spinpage.css # The whole design system and all four layouts
├── js/ # Classic scripts, loaded in this order:
│ ├── core.js # pure game maths: selection, chaos odds, easings, gremlin, hurdles
│ ├── dom.js # element references
│ ├── state.js # game state, derived stats, undo history, save/migrate, commit()
│ ├── audio.js # Web Audio synthesis
│ ├── fx.js # confetti, sparks, fire, flash, shake
│ ├── wheel.js # rendering, spin flow, grab-to-spin, pop-off, strobe
│ ├── events.js # illegal spins, No One Is Safe, PANIC race, gremlin, the winner's moment, autospin
│ ├── slots.js # PANIC's other game: the slot machines
│ └── ui.js # render(), panels, sheets, dialogs, keyboard, settings, boot
├── fonts/ # Cinzel and Oswald (SIL Open Font License), latin + latin-ext
├── tests/ # node:test + playwright-core (dev only)
├── docs/ # Design notes (not deployed)
├── favicon.svg, apple-touch-icon.png, og-image.png, robots.txt, sitemap.xml
└── README.md
The scripts are ordinary <script> tags rather than modules so the page still opens from file://, and their top-level functions stay reachable for browser tests. Every change to the table goes through commit(), which saves once and re-renders everything from state, so no panel can be left showing stale numbers.
localStorage (spinpage), save format v2 — additive, so an older build can still read it.vercelignore keeps tests/ and docs/ off the site)cd tests
npm install # playwright-core only; the site itself has no dependencies
npm test
135 checks in seven suites:
gameplay.test.js — every mechanic, written against the original single-file page and still passing unchanged: selection odds, illegal spins, rigged, flicks, wind-back, gremlin, pop-off, power-ups, the PANIC wedge, race and slots, No One Is Safe, autospin, undo/restore/clear/reset, copy, persistence.stats.test.js — the scoreboard against the game state through every kind of event and reload.layout.test.js — no scroll and nothing off screen at 14 viewports from 320x568 to 1920x1080 and phone landscape; touch targets, keyboard, dialogs, announcements, calm effects.labels.test.js — the names on the wheel, read back from what is drawn: every slice named, long names shortened by the rule in wheel.js, no two slices saying the same thing.review.test.js — what the final review found, pinned down: the result agrees with the draw, no save loses a player, the live numbers stay whole at every width.unit.test.js — the pure logic in Node, no browser, and a check that no two scripts declare the same global.balance.test.js — thousands of whole drafts played through the game's own odds in Node: how long a draft runs at each Chaos level, and that the twists still turn up. node tests/balance.test.js --table prints the lot.The browser suites need a Chromium: they use one already downloaded by Playwright, or set CHROME_PATH, or run npx playwright-core install chromium.
v2.0: the one-screen redesign. The wheel, the controls, the scoreboard and the draft board all fit on one screen with no scrolling, on desktop and on phones. It also brings a new wheel and winner moment, No One Is Safe played on the main wheel, Auto that works at any moment, accessibility and performance work, and the test suite. The full write-up is in docs/redesign-plan.md.v1.0: the original single-file page. To look at it, run git checkout v1.0 (and git checkout master to come back), or browse the v1.0 tag on GitHub.See TODO.md for the running backlog (including the proposed multiplayer "host a room" feature).
No license has been added yet. If you plan to reuse SpinPage publicly, add a license file first. The bundled fonts are under the SIL Open Font License (see fonts/).
Built for the sacred moment when everyone says, "Just spin it already."