Archive for March, 2011

How do you Describe Software?

Monday, March 28th, 2011

I was talking to my father-in-law yesterday. He’s not a software guy, but we were discussing the HR system he uses at work. He speaks very deliberately, always saying exactly what he means. When he was looking for a word to describe the ideal HR software, he settled on “capable”.

Capable. As in, it does what is needed of it.

I love this idea. Whenever a new technology comes out, be it a new framework or a new programming language, everyone wants to talk about how powerful it is. Or how many features it has (and it had better have a lot).

I think we’re going about this all wrong.

When I discover a new tool, I don’t care about how powerful it is or how many features it has. I just want it to be capable. Capable of fixing whatever problem I have. Capable of filling a need. Capable of doing what I need it to do.

Maybe this is how users feel too. They don’t want us to swarm them with bigger and better software. They just want software that is more capable.

What do you think?

Productivity Hack: Still Learning Edition

Friday, March 18th, 2011

A few weeks ago, I set a goal for myself to finally get around to doing the handful of half-started personal projects I’ve promised various people I would finish. I called it Unbroken Promise Month. As you may have guessed from the lack of exciting posts recently, this hasn’t exactly gone according to plan. However, I’ve learned a lot about motivation and myself over the past few weeks, and I’m ready to make a few corrections and carry on. Let’s have a look at the things I tried to do this month that I thought would help keep me focused:

1. Wake up at sunrise every day.

If you follow me on Twitter, you may have noticed that for the first 10 days of March, I posted a picture of the sunrise every morning (like this one). The idea was that I’m not very good at making productive decisions at night, so if I shifted my day by forcing myself to wake up earlier, that would boost my productivity overall. Sounds reasonable, right?

It turns out this sort of helps. I did actually do a few productive things before going to work in the morning some days. This was nice! What happened more often, though, is that I would rush to get to work earlier, and therefore leave work earlier, and have more time in my evenings. This was nice too. It didn’t quite bring in as much extra productivity as I’d hoped, but it did make me more conscious of how I spend my non-work time.

What didn’t work at all was waking up at sunrise on weekends. I’m glad I tried it, but this is simply incompatible with my lifestyle. The sleep deprivation gradually built up, and then I went off on a mini-vacation thinking that I would catch up on sleep and get back to my sunrise mornings upon my return. Of course, that’s not what happened: I actually slept less while out of town, and haven’t hit a sunrise since I left. I need my weekend sleep.

Overall, it looks like I’m going to keep getting up early on weekdays (maybe not at sunrise, but earlier than I woke up for most of 2010), and play it by ear on weekends; I know waking up early doesn’t work, so it’s time to find out what does.

2. No gaming.

I’m not a video game addict by any means, but I did go a bit overboard in February. I played way too much Fallout, and this had a predictably negative effect on me being productive in my spare time. So I figured to help keep me focused for March, I’d cut video games completely.

This sucked.

I don’t know how to say this without sounding pathetic, but I need that time for myself. It calms me down. It makes me a better person (or so the science says). Cutting it completely didn’t help anybody.

This one makes me wonder, though. Normally when I find something that I enjoy a little too much, I set some arbitrary limit and that works just fine. For example, after my job moved to Gatineau, I started eating way too much poutine. Poutine is delicious, but I can feel my heart beat slower while I eat it. A little is okay, but several times per week is absolutely not. So starting in January, I set my limit to one poutine per month, and that’s worked really well so far. I don’t crave it, or struggle to keep myself in line with my limit, and I don’t feel horribly unhealthy for eating a dozen poutines per year.

I don’t know what sort of magic number will work for gaming. It’s a vice. It’s normally not a problem, but every once in a while I decide that I need to cut back, and so I do. I’m still figuring this one out, but zero is definitely not the solution.

3. Dual-boot Linux.

The motivation here is based on that age-old adage re: the separation of work and play. By allowing my PC to boot to Linux in addition to Windows, I can do relaxing, non-productive things in Windows, and exclusively productive things in Linux.

This kind of works. I really do appreciate the separation, but some things have proven difficult to pigeon-hole. Skype is a great example; is that more of a productive tool or more of a slacking-off tool? Well that kind of depends on how you use it. At my day job, we would not be able to function without Skype or something similar. But it can also be a major distraction, interrupting flow and feeding me non-productive links and funny stories.

I’m going to keep it up, but I think I have to start being a bit more lenient on the everything-must-be-productive rule. Skype should be okay. I need to modify my system to allow for it and similar tools.

Carrying On

I knew it was a bit crazy to try to do all of these projects in the same month. I’m still going to try to get many of them done, or at least started, before April. And if I get that far, I’m still marking that down as a win.

Sure, it would have been great to have powered through all of March and caught up on everything I’ve ever wanted to do. But I’m even better off if in exchange for not getting everything done right away, I’ve developed a sustainable set of practices that I can use for the rest of my life.

How to Make a Colour Selector with HTML5 Canvas

Wednesday, March 2nd, 2011

Over the weekend, I attended HackOTT, a hackathon here in Ottawa that encouraged everyone to play around with some neat third-party APIs. It was a lot of fun seeing the awesome apps everyone came up with, and even though we didn’t get to demo, I’m happy with how much I learned.

My team was comprised of myself, my softball captain/ex-coworker @jyboudreau, and our fearless leader @davefp. The idea was that we would create an HTML5 application that allowed users to upload an image of a room, select a few colours from that image, and get back a list of products sold through Shopify that match the room. We were pretty excited, and so were some of the API guys we talked to.

Dave and JY grabbed the TinEye and Shopify APIs, so that left me with the UI. While we didn’t quite manage to get everything working in time to demo, we did make a lot of progress, and I thought I’d share part of my contribution, a Canvas-based app that lets the user pull colour swatches out of an image.

Let’s look at how it works!

Basic Setup

The layout is pretty simple. The empty blocks on either side are just divs that will hold our colour swatches, and that image in the middle is actually a canvas. In fact, it’s two canvases, overlayed on top of each other using some absolute positioning.

We used two canvases to make the drawing easier. The backmost canvas holds our image, and that’s it. The frontmost canvas, which is completely transparent, is where the swatch outlines are drawn. This makes it less expensive to redraw swatch outlines, because we don’t have to reload the image each time, and allows two swatch outlines overlap without having them affect one another’s colour.

Now, let’s have a look at the drawing code.

Loading the Image

Loading an image into a canvas is relatively straightforward. Check out the javascript file, and in particular note the addUserImage function. The mechanics of loading an image are simple:

  1. Create a new logical image:
    var img = new Image();
  2. Make sure the image’s onload function ends by drawing the image:
    context.drawImage(img,0,0,img.width,img.height);
    
  3. Trigger onload by setting the image’s src property:
    img.src = TEST_IMG;
    

There are a couple of gotchas, though:

First, you may have noticed that in the image’s onload lamba, we’re adjusting the dimensions of both canvases and their container. This resizes our canvases and the surrounding layout to match the size of the image. We also set the canvases to display block because they are hidden by default (this avoids an ugly resizing-flash right after the page loads).

Second, the image src can’t be just any image. For canvas to load it properly, it must be an image contained within your own domain. This means you can’t just give it a url you found online, or even load it from a file using localhost. We deployed our app using App Engine, but any container should do the job just fine.

That’s all there is to loading an image, let’s move on to swatches.

Drawing the Swatch Outlines

There are three user events we care about for our canvas: mousedown, mousemove, and mouseup. To handle these events, there are three functions: handleCanvasClick, handleCanvasMouseMove, and handleCanvasMouseUp. Let’s look at these a little more in-depth.

First, you’ll notice that each function uses some simple math to get the coordinates of the mouse click:

var clickX = event.pageX - canvas.offsetLeft;
var clickY = event.pageY - canvas.offsetTop;

We get the coordinates from the page via event.pageX, then subtract the top-left corner of the canvas so that we’re left with the distance of the click from the canvas’s top-left corner. Conveniently, the origin for canvas is located in the top-left corner, so we’re already in the right coordinate space and our x/y positions are ready to use.

Next let’s talk about getSwatchIndex(). This is a convenience function that parses the id of the currently-highlighted div to give us a numerical representation. Why is this important? Because we want to maintain an array that represents the current position of each swatch outline, and we use these numbers to index it.

By storing the positions of the swatch outlines in an array, we’re free to clear the swatch-outline canvas and redraw it completely on each pass. This might seem like overkill, but it’s necessary for situations where two swatch outlines overlap, and at a code level, it’s less work than repainting a transparent box over a swatch outline before the swatch outline is painted again it in its new position.

Once we’ve updated our array, it’s off to our redrawSwatches function to actually draw them. The algorithm here is what you would expect, we loop over the array of swatch outline positions, and draw each one with a semi-transparent background and a solid border. We’re also watching for the currently selected swatch index to come up, because we want to highlight that border with a brighter colour so that the user knows which swatch outline is active.

Handling Dragging

We wanted the user to be able to drag a swatch outline around to make sure it’s placed in exactly the right spot. This ended up being easier than we thought. You may have noticed the dragEnabled variable in our mouse event functions. This is a global boolean that we set on mousedown and clear on mouseup. That way, when mousemove fires, we can check it and redraw if a drag is occurring. Simple!

Extracting Colour Information

Let’s head back to handleCanvasMouseUp and look at the colour extraction (which should probably be in its own function).

The important step is this one:

var imageData = context.getImageData(
    clickX,clickY,HIGHLIGHT_SIZE,HIGHLIGHT_SIZE).data;

Here we’re telling the canvas to give us the image data for a square positioned where the user clicked, and the size of our swatch outline (that I for some reason called a highlight this time — we were in a rush). That returns canvas’s own ImageData object, which probably does all kinds of neat things, but we just wanted the pixels, so we called .data to grab them.

Pixel data in canvas is stored as a giant rgba array. So if you have a 10×10 canvas, then the array will be of size 400 (10x10x4) and will be formatted as [r1, g1, b1, a1, r2, g2, b2, a2, etc]. We want the rgb values only (we skip straight over the alpha values in this case), so we sum up all of the reds, blues and greens individually.

Finally, we average out each colour by dividing it by the number of pixels, floor the totals to get integer values, and voilà! We have an average colour we can show in the swatch.

It was fun spending the day playing around with canvas. Hopefully next time we’ll get something we can demo!