This content originally appeared on DEV Community and was authored by Nathaniel
Here's the link: missingdice.com/spin-the-wheel. I'd really appreciate any feedback on improving it, i've been staring at it for a week!
I've been building a website of simple tools for boardgame players. For various reasons there are times when you need to roll dice, flip cards, or spin a spinner online.
The site is for simple things like that.
I want the site to be a success, so i first took a look at the competition and — for reasons I'll elaborate on in another post — decided that:
- the site should be as accessible as possible
- no page should be larger than
30kB
- every tool should have a
no javascript
fallback
For this tool there we're some interestng hurdles to overcome:
Satisfying Click
It was important that the spinner have a satisfying clicking sound as it spun.
I found an mp3
of a click, but even at less than 1 second long, it weighed 7kB
. Using it would have put me over the 30kB
budget.
I'm sure there are lots of clever ways of reducing the file size of audio. But instead I chose to generate a click with JavaScript
and the Web Audio API Something I hadn't even heard of before now.
Luckily for me, I know a synth enthusiast, and he explained some of the terminology to me.
I found this tutorial on synthesizing drum sounds and tweaked the hi-hat example to fit.
This ended up being just ~1.2kB
of js
- with room for further optimization.
Creating a no-javascript version
To make the spinner work without js
was surprisingly simple.
If the browser has JavaScript
disabled, instead of generating and spinning the wheel on the client-side
, clicking spin the wheel
submits a form…
Then the server:
- builds a spinner with the user's custom values
- randomly selects a winner
- generates in advanced a css animation that spins the wheel
- sends the html back to the client
It works surprisingly well.
I did this with Netlify Functions, so I'm not running an entire server for the tiny number of people who'll use the site without js
.
Animating SVG
While animating SVG is generally fine, some browsers really struggle with it (Safari). After a lot of tinkering, it turns out the best fix is just to use seperate SVGs for each animated component, and put them each in their own <div>
— then animate the <div>
.
Timing the clicks
The spinner spins at different rates, durations, and with a random number of rotations — that way it stays surprising and dramatic.
For the spin to be really satisfying, it needed a little ticker on top. (like on the gameshow "wheel of fortune").
That meant having "pins" around the rim of the wheel, and animating a ticker each time it "hit" a "pin."
For performance reasons I thought it would be better to calculate the timings of the animation (and click sound) in advance.
This turns out to be a seriously complicated task, and after 3 days of learning calculus I gave up.
Instead it uses requestAnimationFrame
and measures the current rotation of the spinner. If the rotation is between certain ranges it produces a click.
This works okay, but it does make mistakes.
It also means the no-javascript
version has no ticker animation.
Spinning with 1000s of values
One issue was allowing people to add 1000s of values to the spinner.
I figured there is a use case where someone might want to paste an entire spreadsheet of values to have one picked at random.
So, I decided to use a <textarea>
as the input, with a new line for each new value. Then, if the user pastes a comma-seperated list, it will reformat it before generating the wheel.
The big problem here is performance.
To make it work, the spinner <svg>
gets less complex as more values are added.
- The patterns are removed.
- The number of pins on the rim of the wheel is capped at
60
- The text paths become simpler.
I've only tested it on my fancy new computer, but it works fine up to around 6000
values. Feel free to test it out and let me know!
Things to Improve!
- The overall look and feel could do with a polish — particularly on the alternate color-schemes.
- The click sound could do with a tweak.
- Finding an accurate way of measuring the click animation in advanced would be amazing.
- Making custom wheels embeddable as an
<iframe>
would be cool.
Let me know what you think and what can be improved?
This content originally appeared on DEV Community and was authored by Nathaniel
Nathaniel | Sciencx (2021-03-22T11:07:41+00:00) Spin the Wheel — a customizable roulette wheel in less than 30kb with a no-javascript fallback.. Retrieved from https://www.scien.cx/2021/03/22/spin-the-wheel-a-customizable-roulette-wheel-in-less-than-30kb-with-a-no-javascript-fallback/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.