Archive for the ‘Software Development’ Category

What Should the Software Industry be Known For?

Monday, December 19th, 2011

I was talking with my friend Marc today. He’s a mechanical engineer (and a damn good one) and we were talking about work. He said something that kind of surprised me:

“Sometimes I wish mechanical engineering companies were more like software companies.”

All through school, and even in the workplace, I’ve heard software engineering compared to traditional engineering.

“You don’t build half a bridge, then change your mind about how it’s going to look.”

“It’s a green-field project.”

“Well, the way they estimate construction projects is like this…”

I’ve always thought other engineering disciplines had all these lessons we could learn in software, given that building software wasn’t recognized as engineering until about 1960*. It’s never once occurred to me that what we do in software could help the guys building cars, or skyscrapers, or in Marc’s case, bomb suits.

This begs the question:

What do we want other industries to say about software engineering?

If you could teach one lesson you’ve learned in software to another discipline, what would it be? What would be the top, absolutely most-important anecdote you could recite? Or inscribe on a statue of a programming icon?

Marc said it was how people are managed. The offices, the lax environment, the 20% time.

I think it’s how we integrate teams. I love working closely with designers, and I bet other engineering fields could really benefit from the software designer/developer relationship, and how it has evolved over the past decade.

Your turn.

What should the software industry be known for?

What Does 6 Months of Developer-Effort Look Like?

Friday, November 11th, 2011

Well, a little something like this:

Word cloud of terms used in timesheet reports.

Image generated using Wordle. Click to enlarge.

Beautiful, isn’t it?

This is a cloud of the most commonly used words in my timesheet entries for a project I worked on over a six-month period. (When you work at a services company, you have to log all your time using archaic worklog software that only works properly in IE7 and below.) Size represents frequency, so the bigger the word, the more I used it to describe what I do.

It’s quite telling.

I’m happy to point out that patch is my most-commonly used word, followed by reviewed. We’re religious about code review at Macadamian, and it’s awesome to me that this is spelled out so clearly in my notes.

Something I’m not as proud of is that tests is a tiny little speck (above the V in reviewed). It’s beaten out by crutch words like etc and sure. Worst of all, we had unit tests set up on this particular project (front-end and service-level). Why did it have such little impact in my notes? This is something that I think I should be spending more time on.

It’s rare to get such a clear glimpse of what my priorities are. I spent nearly 1000 hours of my life on this project, and in one simple image I can see where all that time went. It’s both humbling and encouraging to get this sort of perspective.

What do you think your cloud would look like?

The Key Skill that Makes for a Great Software Architect

Monday, November 7th, 2011

Software architects are a strange breed.

They obsess over code quality. They can’t explain anything without a whiteboard. They adore design patterns that most of us have never even heard of.

When the project is in trouble, they swoop in and save the day.

And they constantly reject my patches.

But I’m thankful for that — all of it. I’ve been fortunate enough to work with some really, really great architects in my (admittedly short) career, and through it all I’ve managed to distill the one skill possessed by every great architect I’ve ever met:

The ability to identify potential pitfalls.

Expecting something more dramatic? Well, tough luck. I know it’s not sexy, but if you want to be a great software architect someday, you need this skill.

Here’s why:

Pitfalls are easy to spot when building a room.

The wife and I are currently finishing our basement. I’m learning a lot during this process, like how to make sure a wall is straight, and the joys of using a ramset.

And of course while I’m swinging that same old hammer into about the fiftieth 3″ nail, my mind starts to correlate what I’m learning about building a room to what I know about building software.

The biggest realization so far?

In simple construction, spotting potential problems is very easy.

If you line up a 2×4, you’re going to notice if it’s not the right size. Measure again, cut again. Problem solved.

If you have to extend some piping, it’s easy to grok the current pipe system and figure out where to make a cut. Plumbing refactored, job well done.

If you’re about to fire a nail through a plank of wood to affix it to the floor, it’s easy to visualize that you’ll have trouble cutting out a doorway there later. Nobody wants to hack through molten metal, so put those nails around where the door is going to be. Crisis averted.

In fact, it’s so trivial to see problems in advance that we’ve yet to make any major mistakes. This is amazing to me! Can you imagine saying anything like that about a software project? (Even a small one?)

Of course you can’t. And you already know why:

Pitfalls are nearly impossible to spot when building software.

How many times have you had to refactor some code you wrote last month, because it wasn’t up-to-snuff? Or had to completely re-write a feature that you implemented earlier in the project?

Seeing potential pitfalls in software is hard.

You would never build a cutting-edge webapp, then turn around and brag about how you got everything right on the first try. Your fellow developers would think you’re crazy, and your QA wouldn’t be able to stop laughing.

Every software developer makes mistakes all the time. Functions that aren’t quite single-purpose, dependencies that aren’t strictly necessary, routines that are a little too verbose. And we always end up paying for it later. Who will save us from this madness?

Architects, that’s who.

Great software architects mitigate rework and lost time by identifying pitfalls in advance.

They can look at a framework and tell you if it’s too abstract or not abstract enough. They can examine an existing codebase, and have a pretty good idea of where to start refactoring. They can tell when a new patch is going to break a valuable design pattern, or introduce inconsistencies into the codebase, or need to be re-written before the end of the next sprint.

This skill, this ability to look at some seemingly-harmless change and intrinsically know what problems it will cause later — it’s amazing. I don’t understand how they do it, and I don’t know if I’ll ever acquire that talent.

But I know it’s something I admire. And if you ever want to become a great software architect, this is the one thing you need to get right.

Now if you’ll excuse me, I have to go fix up my latest patch…

Classics Week #1: What Photography and Programming have in Common

Monday, September 26th, 2011

This post is part of the Classics Week(s) feature, which will run for three weeks while I’m off overseas. It’s the first of three posts from the early days of the blog, dug up from the archive and polished ’til good as new!

Ladies and gentlemen, allow me to share with you a tale of two photographers.

Back in the summer of 2010, my fiancée and I were featured in a piece for our local newspaper. The columnist wanted an image to accompany her content, and sent a photographer to our apartment to take a photo of me and my soon-to-be bride.

The photography session played out as I’d expected. Some nondescript ‘dude’ with a camera sauntered in, looked around the room for all of about six seconds, arranged a semi-interesting shot involving a mirror, snapped a few pictures and left. Took around ten minutes.

A few days later, the writer called back and asked if she could send over another photographer. Apparently the shot the boring fellow took was too similar to a shot the newspaper was running on another article — on the same day, in the same section — so they needed a different one.

The second photographer was Christopher Pike.

Christopher ran things a bit differently. After introducing himself, he spent a few minutes looking around our humble abode and the surrounding area. He then asked what my fiancée and I thought of a few potential shots, and started taking pictures.

Many pictures.

We posed on our balcony. We posed on a bench. We posed near a wall, and then next to a fence. Every time Christopher noticed something that might make for a cool shot, he asked if we wouldn’t mind another photo.

After about an hour of this, he thanked us and left.

Like the first photographer, Christopher was a freelancer hired by the newspaper. Presumably, the two of them were each paid the same amount for their work. But while the former spent ten minutes taking a picture he had decided upon in advance, Christopher spent seven times that long experimenting and looking for the perfect shot.

What does this have to do with programming?

Just like photography, programming is a craft.

That first photographer, the one whose name I couldn’t be bothered to remember, was just in it for the job. The columnist wanted a cute photo of a young couple, so our unremarkable photographer snapped an equally (un)impressive shot, and left.

This is how unremarkable coders look at programming. You need a function that converts X inputs into Y outputs? Sure. Let me whip up a quick algorithm that does that. Done. What’s next?

Christopher, on the other hand, was there to take great pictures.

He was passionate, and he approached photography as a craft. Yes, the result was still just a photo to sell to a newspaper, but believe me when I tell you that’s not why Christopher is a photographer.

Here’s how I look at coding (and hopefully how you do too):

You need a function that converts X inputs into Y outputs? Ok. Let’s first consider the context, ask a few questions, then create a proper solution. Functionally, it may be the same as Joe-first-photographer’s solution, but a programmer that cares about his craft took the time to:

  • Verify that a single function is in fact the best solution.
  • Keep future maintenance and extensibility in mind.
  • Write clear, reusable code.
  • Add useful comments when necessary.
  • Refactor the function to be as simple as possible.
  • Switch spaces to tabs to match the existing code-base.

Which photographer would you rather hire?

Which programmer would you rather have on your team?

Wicked Hacks for your Mac

Monday, September 12th, 2011

I’ve been using a Mac at work for the past few months. It’s refreshing.

My first computer that was actually my very own computer was an iBook (G3) back in 2003 or so. I loved it. I downloaded all kinds of software to make it do interesting things (or do boring things in interesting ways), and when I ran out of things to download I fired up Applescript Editor and wrote some myself.

Having not used a Mac regularly for a few years, I was a bit curious to see how quickly I would get back to my old ways when I was put on an iPad project. The answer: not long.

I thought it might be fun to share my setup in case some of these tools are useful to anyone else. For posterity, I’m using Snow Leopard on a Mac Mini, with a standard Apple keyboard and a Magic Mouse. (Lion and a touchpad should work just as well.)

Let’s start with the easy stuff.

Even without any mucking around, OSX is somewhat configurable. One of the first things I did on my new office Mac was re-map the Exposé hotkeys.

The default function keys are nice, but on the keyboard accompanying my Mini, I have to hold down the Fn key before hitting F11 to reach Show Desktop. This is annoying; I use that functionality all the time, and those keys are on opposite corners of my keyboard. System Preferences to the rescue:

By opening System Preferences, then Exposé and Spaces, you can re-wire the hotkeys for Exposé settings.

I use Right-Command, Right-Control, and Right-Shift for All Windows, Application Windows, and Show Desktop respectively.

Another big one is Hot Corners. A lot of people like to map Exposé-type actions here, but I prefer screen-related actions. The only one I have set right now is my top-right corner, which puts the entire display to sleep.

That’s not all a vanilla install can do, either. Check out System Preferences > Keyboard and Mouse > Keyboard Shortcuts for more options.

Hide and seek.

Hide is my favourite feature of OSX. In any application, press Cmd+H and the app will disappear. This is not the same as minimize, which eats valuable Dock-space; hide causes all application windows to completely vanish. To access a hidden application, either re-launch it or cycle to it using Cmd+Tab.

That’s good already, but for applications I use all the time, I like to have a single, global access shortcut. What I want is to hide the app if it is open, and bring it back into view if it’s hidden. I do this with a handy Applescript that looks like this:


if application "Application" is frontmost then
    tell application "Finder" to set visible of process "Application" to false
else
    tell application "Application" to activate
endif

Replace “Application” with the name of whatever application you want to show/hide, and voilà! You’re all set!

Well, almost. We still need a way to bind that script to a single action. Now how are we going to do that?

Enter BetterTouchTool.

BetterTouchTool is a shareware application that adds improved touch events to OSX. It works beautifully with my Magic Mouse, and I’ve heard it’s just as useful for trackpads on all flavours of Macbook.

That show/hide script is one use, but I have others set up as well:

  • Two-finger swipe up: Home (scroll to top of page).
  • Two-finger swipe down: End (scroll to bottom of page).
  • Two-finger tap: Show/hide Mail.
  • Three-finger tap: Show/hide iCal.
  • Two-finger click: Zoom (the green button in OSX window toolbars).
  • Three-finger click: Launch Divvy.

In general, I like to give mouse actions to tasks that will be followed by more mouse actions. For example, I also have a show/hide script for Skype, but I’ve mapped that to a keyboard shortcut; I’m going to be typing as soon as I get into Skype, so I might as well use my keyboard to get there in the first place. For apps where I tend to be more mouse-focused, like Mail and iCal, it makes more sense to access them from my mouse.

I’ll also re-map actions that I find hard to use. That zoom button is pretty out of the way, a two-finger click anywhere on the screen is much nicer. Same for Home/End, especially since I generally scroll with the mouse anyway.

Divvy is another obvious candidate for a mouse-based trigger. If you’re unfamiliar with it, go check out what it can do — it’s a great tool for managing window sizes/locations.

Bring on Quicksilver!

Quicksilver is easily my all-time favourite OSX application. I use it constantly, and it’s the very first thing I installed when our IT guy dropped off a Mini at my desk.

I could write an entire ebook about why Quicksilver is the best thing that’s happened to MacOS since the transition to OSX, but I’ll stick to two main bullet points describing what QS is:

  1. A keyboard launcher.
  2. A trigger-management tool.

That first point is boring and I’m not going to cover it. There are plenty of other keyboard launchers out there, and they all work about the same way as far as “opening applications with your keyboard” goes.

Now triggers, that’s where things get interesting.

Like BetterTouchTool, Quicksilver lets you run scripts and other actions when “something happens”. In this case, something happening can be as simple as a hotkey being pressed, but plugins for QS add many more interesting possibilities. (We’ll get to my favourite shortly.)

I’m going to start with my hotkey setup. As I hinted at already, I have one of my show/hide scripts bound to Skype. I trigger it with F6. I find this is really useful for “peeking” at Skype to see if any important IMs require my attention — one touch to bring it up, another to dismiss it, and my tab order is unaffected.

I’ve also mapped some hotkeys specific to iOS development: I’m such a fan of Cmd+Ctrl+Up Arrow and Cmd+Ctrl+Down Arrow (for switching between .m and .h files) that I’ve set application-specific hotkeys in XCode and the iOS Simulator to switch between one another on Cmd+Optn+Ctrl+Up Arrow and Cmd+Optn+Ctrl+Down Arrow.

I have another app-specific key binding on my iOS Simulator: I’m working on an iPad application that requires login on start-up, and a while back they changed the default user’s password from “jones123″ to “Oncologist”. I don’t know about you, but I can’t reliably type Oncologist (case-sensitive!) when I’m half-awake at the tail end of a twelve-hour day. So, I scripted it:


tell application "System Events" to keystroke "Oncologist"

This simple script fires whenever I hit Fn+Enter inside the iOS Simulator. It’s immensely convenient, and much faster than typing myself (even if you don’t count the time wasted when I don’t get it right).

I’ve also added a global hotkey to trigger screen lock. Quicksilver provides some convenient options for hotkey events, and the one I used here was the “Hold for” modifier. Now, when I hold Esc for a couple of seconds, QS fires a call to OSX’s built-in screen lock. It’s a little finicky, and my real usage is more like “mash Esc for a few seconds”, but hey, it’s a throwback to how I use vim :)

Ready for something a little more novel?

The magic word.

Abracadabra is a Quicksilver plugin that lets you activate triggers by drawing custom shapes on the screen with your mouse pointer. Sound a bit crazy? It is. And really useful too! This is much better explained with video, and fortunately there’s an Abracadabra screencast you can check out to see it in action (along with how to install it).

I have a couple of simple drawing gestures in place to control system volume: A straight line up for louder and a straight line down for quieter. I’m also a total neat-freak when it comes to my Downloads folder. I clear it out several times per day, and using Abracadabra, I trigger a purge by drawing an X on-screen. It’s super-cool!

Here are the scripts if you’re curious:


set currentVol to (get (output volume of (get volume settings)))
set volume output volume (currentVol + 10)

set currentVol to (get (output volume of (get volume settings)))
set volume output volume (currentVol - 10)

set pathToDownloads to "~/Downloads"
set pathToMailDownloads to "~/Library/Mail Downloads"

tell application "System Events"
    set filesInDownloads to every disk item of folder pathToDownloads
    repeat with eachFile in filesInDownloads
        delete eachFile
    end repeat
end tell

tell application "System Events"
    set filesInMailDownloads to every disk item of folder pathToMailDownloads
    repeat with eachFile in filesInMailDownloads
        delete eachFile
    end repeat
end tell

For the music lovers…

iTunes is heavily scriptable. Back on my iBook, I had all kinds of scripts wired up to Abracadabra for changing tracks, toggling shuffle, and all sorts of other functionality.

But lately, I’ve moved to Grooveshark.

Since Grooveshark is a webapp, it’s not very accessible to Applescript or apps like BetterTouchTool and Quicksilver. It also slows Safari to a crawl.

These issues can be solved by running Grooveshark in a single-site browser. I’ve taken a liking to Fluid.

Now that Grooveshark is running in its own application space, we can do all kinds of neat things to it. For now, I’m content with only a couple of scripts:

As you might expect, I have a show/hide script set up for it. This one is triggered via Abracadabra (I invoke it by drawing the musical sign for a flat). I also have a play/pause script, again triggered by Abracadabra, this time with a horizontal line (the fastest, easiest thing to draw).

I tend to stick to Abracadabra for music-related actions; it’s a bit of a tradition as this is what I used Abra for on my old iBook. Hotkeys, BetterTouchTool events, and any other action that lets you run an Applescript will work just as well.

Talk like a duck.

Lastly, you may have noticed a tweet I sent out the other day about Adium and Growl. Here’s a longer description of that hack:

If you use Adium (and you should, it’s a fantastic multi-account IM-chat app) you can have Growl deliver your notifications. This will put little, unobtrusive pop-ups on your screen, alerting you of Adium events. New messages, contacts going online/offline, that sort of thing.

Adium’s notifications are highly customizable, and likewise for Growl. Better yet, Growl provides a number of different formats for its messages. Most are visual, but I recently noticed there’s one called “Speech”.

If you open System Preferences > Growl > Applications > Adium > Configure and set the Display Style to Speech, Adium’s notifications will be read to you, out loud, in a default OS-system voice.

I absolutely love this for message alerts when Adium is not in focus. I can continue to wrap up what I’m doing, half-listening to whatever Growl is reading out. This allows me to judge whether the incoming IM is worth interrupting my current task for, and if it isn’t, I can just keep on working.

I’ve only had it live for a few days, and of course this kind of behavior will get spammy if you don’t wear headphones regularly or you get a ton of IMs from Adium, but I get downright giddy every time it goes off.

The scripts.

I can’t give you a download that will set up Quicksilver, et al. for you, but I can hook you up with a convenient zip of the various scripts I’ve mentioned above.

(I’m not providing a license; they’re a gift. Use them however you please.)

What are your hacks?

Now it’s your turn to share.

I’d love to hear what you’re doing to optimize your environment. Do you use any of the hacks above? What else are you fond of? Am I overlooking anything especially awesome?

Happy hacking!

Motivation Hack: Make Annoying Tasks Fun!

Tuesday, August 30th, 2011

Motivation is a tricky thing. Sometimes it can cause us to complete wildly-improbable tasks, other times it can cause us to dread even the simplest of chores.

The software I’m creating at work has one such chore. Our application interacts with a complex, proprietary, and highly-secure server. One of the consequences of this pattern is that we have to deal with security tokens.

Tokens forsaken.

It works like this: Whenever someone logs into the app, the server issues them a security token. From that point on, all communication between the app and the server must use this token. Easy, right?

Tokens purged.

The chore is this: Due to some wonky bug that is beyond our control, the server can only issue a few dozen tokens, and they’re not renewed properly. We’ve never counted it out, but I’d estimate the server can grant tokens for a hundred or so logins before it runs out.

Tokens scrapped.

When this happens, and it happens every couple of hours, someone needs to manually access some web form and click around a few times to reset the tokens. This is a pain for two reasons.

Tokens obliterated.

First, it interrupts whoever is trying to run the app. Maybe it’s QA breaking my stuff, or our PM showing the app to somebody important, or a dev like myself just trying to validate his latest code change. Whoever is unlucky enough to see the login fail must run through all the token-resetting hoops, and then context-switch back into real-work mode.

Tokens repudiated.

Second, nullifying the tokens will kill any and all existing sessions on the server. So if QA got the last token and is in the middle of a test sequence, and I try to log in next, and fail, and reset the tokens, then QA’s session is suddenly invalid and they’ll start seeing errors left and right.

Tokens slain.

So to stop QA from logging a whole whack of bugs that would be impossible to reproduce, we came up with a system. Whoever resets the tokens lets the rest of the team know by sending a message to our project’s group-chat in Skype.

Just murdered the tokens.

See? Like that.

This was really annoying, especially since we had to do it many times per day. There was much complaining, and clamoring about getting a new version of the server that might solve our problem.

Then, something changed.

Tokens punched in the face and had their milk-money stolen.

We made a rule: Every time you clear the tokens, your message to the group must be unique. At first, we saw a lot of synonyms for “killed”. When we grew tired of running to a thesaurus every few hours, we started getting more creative with our phrasing:

Tokens are dead, and their heads have been mounted on pikes to warn future tokens to stay away.

Topical, even. We would hit movie quotes, the latest news, memes… Nothing was off-limits.

Tokens defeated by attacking their weak points for massive damage.

It became a game. Who could come up with the most creative token-killing message? Who could get the most laughs?

Tokens were eaten by a grue.

Our moods did a full 180 from a few weeks prior. Instead of feeling frustration when I see that login failed error, I now feel excitement. “I have just the thing!” I proclaim, and off I go to reset the tokens before anyone else notices and beats me to it.

Down came the rain and washed the tokens out. Then, I shot them.

We successfully turned a real headache into a fun experience. Morale went up. And a happy team is a productive team!

Tokens fed through a detokenizer.

I’m going to look for other places where joy can replace annoyance. Maybe you can do the same?

You maniacs! You blew them tokens up! Damn you! Damn you all to heeeeeell!

Find me at MIX 2011!

Monday, April 11th, 2011

By the time this post goes live, I’ll be in Las Vegas for MIX 2011.

Follow along!

As I’m there on behalf of my workplace, I’ll be blogging up a storm on the Macadamian blog. I’ll also be tweeting primarily under the company moniker, @macadamianlabs.

It’s going to be awesome!

I’ll be demonstrating the famous Windows Phone 7 Isolated Storage Explorer (made by Romeo Dumitrescu, one of Macadamian Romania’s newest tech leads) at Open Source Fest on Monday.

I’ll also be attending boot camps, speaking sessions (both big and small), and various attendee and Microsoft-sponsored parties, all of which I’m very excited for.

If you’re at MIX, please say hi!

Tweet me at my personal account (@dan_menard) or Macadamian’s official account (@macadamianlabs), or send me an email. I’d be happy to meet up with you to chat, catch a session, or grab a drink.

Finally, any advice for a first-time MIX attendee? Thankfully it’s not my first time in Vegas, we all know how that ended up.

Creating Software isn’t a Job…

Monday, April 4th, 2011

…It’s a lifestyle. I’ll explain why in a second, but first let’s get some context.

Here are a couple of people that are in the wrong profession:

We’ll start with the engineer. If he were a character in The Wizard of Oz, I can tell you what the Wizard’s diagnosis would be: He has no passion. He thinks he can just phone in his programming career in a 9–5 setting and be done with it.

The cargo-cultist is a more interesting case. Here’s a young man that is trying to decide if programming is the right career for him. He wants to become a better programmer, but he’s unsure about his skillset. He (wrongly) blames his learning abilities for his shortcomings, when really he has all the tools he needs to succeed — He’s simply not motivated enough.

There’s a simple fact that neither of these gentleman have yet realized:

Software is art.

Being a software developer is like being an artist. You aren’t just creative for 8 hours a day. You can’t turn it on and off. Your motivation to create ebbs and flows around the clock.

Not into the art thing? Fine. Here’s my* other analogy.

Programming is a sport.

A competitive one, like soccer football.

Do you think footballers only play football during games? Or even just games and practices? Of course not. They love football. They play as much as they can.

Would anyone ever think it’s stupid that footballers make jokes about football? Or play football on weekends? Or try to change the world by kicking a ball? Never.

Near the end of a losing streak, do the players blame their skills? Is everyone else just more talented? Don’t make me laugh. They get out there and train as hard as they can, because they love what they do.

And so do we.

If you’ve any doubt left, it’s time to start thinking about your next gig…


* Ok, so this wasn’t entirely my metaphor; hat tip to davefp for the assist :)

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?

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!