Project #1: Honeybee Spinner

My uncle Joe is a pretty amazing person.  Although he doesn’t label himself as an environmentalist, Joe devotes his evenings and weekends to improving the local ecosystem.  He has always been a good neighbor — in fact, he met my aunt 35 years ago when they bought townhouses next to each other!  Now he concentrates on cultivating some more unusual neighbors: his community’s bees.

If you’ve watched Vanishing of the Bees, you know that without healthy bee colonies, our grocery stores would be empty.   Joe maintains bee hives locally and and educates fellow beekeepers across the US on how to breed queens and nurture healthy hives.

Joe approached me last year with a request: he was schlepping a large beekeeper’s calendar out to the hives to help him figure out the larval stage of the queens.  Would it be possible to convert his calendar into a mobile app?

I said yes immediately.  I’ve been working in my company codebase for so long that I needed a refresher on setting up my own project.  Plus, it would be a great chance to practice animation.  The calendar is round, so it needed to be able to spin.

I don’t do any animation for work, so I ended up losing some time scrolling through the wrong kinds of libraries — number spinners and loading spinners and SVG generators that draw circles based on a model.  I needed a way to spin a wheel based on user input, preferably spinning it along with the user’s drag.

Finally, I resigned myself to writing the code from scratch.  I wrote something that did almost what I wanted:

var rotation = 0;
var wheel = document.querySelector('img');
document.querySelector('.spinner-large').addEventListener('drag', function (event) {
    totalDrag = (event.clientX + event.clientY);
    rotation += totalDrag / 720; = 'rotate(' + rotation + 'deg)';

What I didn’t account for is that the HTML5 ‘drag’ event is intended for drag and drop, so the user’s drag is going to cause a duplicate image to actually appear and move separate from the wheel spin (demo pen).  Not going to work.

After more research, I figured out that the way to do this is not with ‘drag’, but the ‘mousedown’, ‘mousemove’, and ‘mouseup’ events.  Thus, set draggable=”false” in the HTML to prevent that second image from appearing.  Then if ‘mousedown’ is happening inside the bounds of the image, allow ‘mousemove’ to change the wheel’s CSS rotation.

My wheel was now working.  The math on the rotation wasn’t precise, but it worked for Joe’s very basic use case.

Once I figured this out, I searched again with more specific search terms and was able to find this JavaScript Rotate Dial example, which spins the wheel with better precision and browser support than my code (demo pen). Deus ex machina, anyone?

I’m glad I didn’t find this at first, though.  By drafting the animation myself, I learned a lot about about JS vs. CSS rotation (CSS rotation was WAY easier), standard HTML5 events, plus I discovered some amazing libraries that I may want to use someday (jQuery knob, I’m looking at you).

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s