Author: ginna

Software dev specializing in MVC frameworks and fullstack JavaScript.

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;
    wheel.style.webkitTransform = 'rotate(' + rotation + 'deg)';
    event.preventDefault();
})

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).

Advertisements

Scrapping my work — again

I discovered a new emoji this week: the volcano.  Screen Shot 2016-07-19 at 11.58.32 AM

To date, the crocodile has been my go-to emoji for expressing rage.  For example:

This lady with weird pants almost hit me with her bike this morning on Broadway.  crocodie

My coworker called a meeting and didn’t even bother to show up.  crocodie

Someone else took the last swedish fish from the snack jar.  crocodie

But this week, my emoji needs reached a whole new level.   I was trying to get final specs on a new feature, into which I had already poured a number of hours.  After a lot of unhelpful answers over slack from the people who were supposed to be planning the feature, I got a final message:

“Hey don’t worry about this feature too much.  Once you make it we can have people try it out and then we can always just roll it back.”

Screen Shot 2016-07-19 at 11.58.32 AMScreen Shot 2016-07-19 at 11.58.32 AMScreen Shot 2016-07-19 at 11.58.32 AM

Irritating exchanges aside, this is one of the things that has been hard to get used to in software — the idea that everything I do can and will be scrapped, sometimes by me, sometimes the next day, often without a trace of my original labors.

In past jobs for government contractors, nonprofits, and universities, everything I did led somewhere.  My edits were incorporated, my proposals submitted.  Redoing something from scratch was a rarity– if it was bad enough to need redoing, the boss would probably give it to someone else anyway.

Fast-forward to today: rewriting code galls me.  It says to me that I’m just a code monkey who is that much closer to death, that if people respected my time this wouldn’t happen — even though I’m just as often to blame for mistakes.  Every minute I spend redoing something feels like further confirmation of my own worthlessness.  “I may as well not even be here,” I think to myself bitterly as I start cherry-picking commits.

And yet.  My boss offered some encouraging feedback in my annual review last month.  After telling me how happy they are to have me as part of the team for 2016, he offered some constructive feedback.  He encouraged me to be patient and flexible around redoing things. (He knows how bent out of shape I get about this stuff, having received his fair share ofcrocodie.)  He reminded me that reworking is part of the software development process, part of life, and it’s not really a sign of personal shortcoming.  In fact, refusing to rework a feature or to improve it would be the shortcoming.

I still hate redoing things — that hasn’t changed — but I’m starting to see this struggle as an opportunity to practice patience with my sometimes frustrating reality.  No software, not even my own AHEM flawless code, lasts forever.  Heck, in a few years, we’ll scrap this entire code base and rewrite from scratch using the fad JS framework of 2020. Moreover, even a task as mundane as refactoring can offer the opportunity to for reflection and even — dare I say — innovation.

 

 

2016: Ten Tiny Projects

At the beginning of 2015, while preparing to start my first full-time JavaScript role, I set some pretty ambitious goals for the year, things like reading ES6 (all of it), learning ReactJS, making a major d3JS web app.

Looking back at the long list of goals, I made progress on several of them, but not as much as I had hoped.  Realistic goal setting?  Not so much.

To be fair, I did start several personal projects, but they were just too ambitious:

  • I built a fan page for my favorite novel Jonathan Strange & Mr Norrell (which is now a BBC miniseries) in angularJS and SASS, but it sucked content-wise, to put it mildly. (Unless you count the illegally obtained illustrations from the novel itself, which were pretty awesome.)  I had planned some visualizations worthy of the magical subject matter  — inspiration here and here, but ran aground when I was unable to find an electronic copy of the text.
  • I started working with d3JS to build some innovative visualizations. So far, my first viz has a carrot, a cookie, and 5 sheep in it, the latter grazing dully in a perfectly straight line. Still working on this one.

It’s a shame I don’t have anything to show for these and other false starts, because I learned a lot just from setting up the codebase for these projects. I think I just need to take the ambition level down a notch next year.  Essentially, I need to set goals like a true engineer solves problems — by breaking them down into the smallest possible pieces.  In 2016, instead of aiming to complete several big projects, my goal is to do ten tiny projects — about one 4-hour project per month.

First project — making a simple d3JS viz from scratch.  Not an innovative viz.  Just your run-of-the-mill bread-and-butter janky data viz, hopefully not so janky as to be illegible.  But I’m getting ahead of myself.

If this sounds like the sort of thing you’d like to see, stay tuned.  2016 is just getting started.