What to Eat in Nashua

Leaving the house is a rare event for Nashuans, but in case you decide to try it, here’s a short guide to eating in the city.

Hipp hipp hurra! Konstnärsfest på Skagen - Peder Severin Krøyer

Nashua residents drinking. This is foreshadowing.

Breakfast & Bakeries

Every day starts with coffee. If you live in New Hampshire and don’t start your day with coffee, Jet Blue has $49 flights to Florida and you’re welcome to leave any time.

Riverwalk Cafe has the best coffee in Nashua, roasted in house, and is the correct place to start your morning. Entering the cafe places you in a warm and bright blue room, with food coming out of the kitchen while coffee is roasted next to you. Walk past this scene and enter a darker and larger room with walls made of bricks and a wall of alcohol, which you can mentally bookmark for later. Or now. There’s no shame in the mimosa. Light filters in from outside, from the ceiling, from lights inside of bottles. Forks dangle upside-down next to your head while you order. You wonder if the decor is intended to represent the confusion of waking up. Order your coffee and go sit in the blue room, next to a large framed print of John Lennon screaming at a piano.

For an even more psychedelic coffee experience, ask for a Hungarian. Never get one to go.

The diner experience is to be had at The City Room. The menu is neither special nor interesting and the coffee is bad, but the staff are very friendly and you can ask for anything. If you eat here, go to Riverwalk afterwards for coffee.

Bagel Alley is your neighborhood drug dealer for oversized bagels. Just like your other dealers, they only work in cash. They sell a few other things, but the inside silently screams “do not buy anything here but bagels.” New Yorkers will be disappointed, obviously, because they’re disappointed with everything.

Pressed in South Nashua has a very industrial feel, which I don’t like, but the highly reliable service justifies the look. The food is probably the most interesting in Nashua for breakfast and lunch. Try the Medusa or the Shakshuka.

Jajabelles are the masters of everything sweet, right down to the people themselves. They also have some savory pastries like Spanakopita. They do not have pastitsio, no matter how many times you ask. They do holiday ordering if you want to get 100 cookies or a plate of baklava for your family.

There are zero good bread bakeries in Nashua. The Dutch Epicure in Amherst is your best bet. Wednesday only they bake anadama bread (sourdough with cornmeal and molasses). Buckley’s Bakery in Merrimack also has good bread.

For really interesting breakfast spots, you’ll have to leave Nashua:

  • Riverhouse in Milford has some great creations. (Afterwards go to the excellent Union Coffee for coffee)
  • Hilltop Cafe is in an old farm-house in Wilton and especially nice in the summertime
  • Black Forest Cafe & Bakery has a good brunch on Sundays only. Also the best hot chocolate I’ve ever had, complete with a whiskey-cube-sized marshmallow.

Fancy

The pickings for quality dining in Nashua are slim, but there are more good dinner options than breakfast options.

MT’s Local Kitchen & Wine Bar is the obvious choice for “New American” or Ameri-French food. It’s owned by Michael Buckley, who also owns Surf across the street (and a second Surf in Portsmouth), Buckley’s Great Steaks in Merrimack, and Buckley’s Bakery and Cafe in Merrimack.

All of Michael Buckley’s restaurants are worth trying, though in recent years MT’s is guilty of simplifying their menu to the point of boredom. (Also, Buckley, Giard, if you’re reading this, why did you drop the glorious pesto fries for these dry-mouth inducing “cheddar dusted” fries? And why would you ever describe cheese as something you can dust with.)

At both MT’s and Buckey’s the burgers are made from steak trimmings are are the best in the area. At MT’s get the Tournedos. At Buckley’s, split the French onion soup with your lover and get the little filet au poivre. Both places also have daily specials which are usually the most interesting options. Any lamb option that comes up is a good choice.

Stella Blu is the other good option for fancy food at night. Lots of small plates to choose from, so bring a friend or two and split several dishes. The menu is varied, the service is quick, the cocktails are good. It’s not on their drink list, but ask for a wagon wheel: Woodford Reserve bourbon, amaretto, peach schnapps.

The menu at Pig Tale looks promising but the the restaurant does not play the part. The atmosphere radiates a feeling of disbelief, as if you’re not really in a restaurant, but on a stage with actors and everyone is pretending to be in a restaurant. It’s hard to describe. Anyway I like their pizzas, but I’ve also had the worst poutine of my life there. If you want sublime poutine you have to drive 2 hours to Duckfat in Portland. Maybe Pig Tale is worth more exploration, I don’t know.

For Greek and Italian you have Giorgios (get the arancini, gyro appetizer, pasta specials) and Cucina Toscana (modest Italian). Do not go to Fratellos Italian Grille, it is pseudo-Italian rubbish. Besides “grill” in Italian is “griglia,” so quit with the pretentious spelling.

For really good and interesting Italian you’ll have to leave Nashua. Tuscan Kitchen is half an hour away and is also one of the few places to buy decent salami. (If anyone knows another place to get great fermented meats nearby, I’m all ears). Filho’s Cucina in Groton is also very good Italian.

For seafood you have Surf, obviously, but also Sushi options: Takumi is fancy, Yoshimama is not. Both are good. Sushi anywhere else in Nashua is not advised.

You might be tempted to go to the Cape for fancy seafood, but this is a mistake, because then you’d be on the Cape: Surrounded by idle rich people who have declared their lives pointless and set up camp on an uninviting peninsula, soaking themselves in sun, apathy, and liquor. Portland Maine is always the better pick.

(Tip for New England newcomers: The proper way to eat seafood is less than a mile from the coast in a seedy shack that just says “Clams” and the sign doesn’t light up. Maybe there’s a string of buoys outside on a rope.)

No Frills

We can’t be bourgeois all of the time, and while Nashua may or may not do “not fancy” well, they do it often.

Main Street Gyro is a go to place for gyros, obviously. Try the bifteki. If you’re starving, get the side of feta too. It is exactly what it says it is. Similar and undderrated Lebanese food (shawarma, falafel, etc) can be found at Cedars Cafe, which is sadly not downtown or I’d go there all the time.

Have you ever been famished and desperately in need of energy, so you eat food, but after eating the food you feel slightly closer to your death instead of further away? That’s Riverside Barbecue.

California Burrito looks promising but, confession time, I’ve still never been there. Trusted friends call it a surprisingly good and more authentic version of Chipotle. The only other Mexican I’d step into in Nashua is El Colima, which is not an endorsement, I’m just saying everything else is worse. Go to El Rincon in Manchester if you want Mexican food.

For good pizza you’ll have to stray outside of the city slightly. Angela’s Coal-fired Pizza in Tyngsboro is very good. MT’s and Giorgios (Merrimack and Milford) make great pizza too.

The Peddler’s Daughter is your typical Irish pub and probably shows up on Google Maps with tags like “popular with locals”, for whatever that’s worth. The vibe is comfy and there’s no hope of getting a small meal. It sounds like a paradox, but Peddlers has both the largest and the worst beer list. Their liquor options aren’t impressive either, I don’t think they’ve ever stocked a bottle of wine that they paid more than $5 for. One time in a whiskey mood and keeping my expectations low, I asked for Wild Turkey. The bartender looked and said “We have Old Crow.” My college degree allowed me to observe that these are both whiskeys named after birds, but drinking confirmed other differences.

The Nashua Garden sells sandwiches and beer. The place appears run-down from the outside, and from the inside too for that matter, but they really do care about the product they’re selling. It’s one of the few places to get a decent meal late at night in Nashua, and can be fairly quiet (downstairs) late into the night. They clean their tap lines regularly, and I want to say they have a good beer selection but I swear 90% of them are always IPAs.

Codex, Stella, MT’s, and Buckleys are other good places to drink. Codex and Stella do mostly cocktails, MT’s has great wine with an OK spirits selection, and Buckley’s has both a fantastic wine and whiskey menu.

If you’re a true drink aficionado you could join one of the many secret liquor tasting clubs, if only you knew the password. No I won’t tell you a password. Unless you’re part of the “old Hollis men who drink nice wine” club, then maybe we can exchange passwords.

Asian

I have categorized food as either fancy, not fancy, or Asian. This is not my fault. For Americans, “Asian food” typically represents the fanciness of far-group exotification with the completely unfair expectation of no-frills price points. (Sushi excepted, but I already covered that.) I blame my countrymen for largely ruining Thai and Chinese food with the “it has to be cheap” expectation.

Takumi is good Japanese. Yoshimama has good sushi as I said before, and they do have ramen, but the ramen quality has declined. It used to be a great cut of rare beef and now you are served slivers of something gray. If you’ve never been to Takumi before, try sharing several appetizers with friends: beef tataki, edamame, and tempura.

The only good Chinese in the city is Shanghai Osaka. Their menu has an “Authentic Chinese” section and they usually have a second menu with more authentic chinese specials. If you like spicy food, try the mapo or sirloin in chef’s chili sauce. The eggplant is also good.

Fantastic Sichuan Chinese food can be had “nearby” in Billerica, at Sichuan Gourmet. The correct way to eat real Chinese food is to bring lots of friends, order lots of dishes, and share everything. Start with: dan dan noodles, bamboo in spicy sauce, wontons in chili oil, basil eggplant, baby bok choy, dry shredded beef with chili, and ma la lamb.

Shira Kiku has great Korean staples (and ramen) and the staff are super friendly. If you’ve never had Korean before, get the stone pot bibimbap, preferably with beef. Don’t be afraid to ask for help with the menu.

Giant of Siam on main street is your average Thai place and has been a Nashua staple since I’ve been alive. The prices are cheap and the owners are super nice. Sweet Ginger in Merrimack has more interesting options, but the atmosphere seems to scream “I’m in a strip mall between a liquor store and a highway” (you are). All of the duck options at Sweet Ginger are good.

For really good Thai you’ll have to travel all the way to Camden Maine (Long Grain).

Nashua has three Indian restaurants: India Palace and Taj India, which have dishes characteristic of north Indian food: Chicken tikka masala, lamb, lots of cream. Both are good. If you’ve never had (north) Indian before, order chicken tikka, saag paneer, and garlic naan. For south Indian there’s Udupi: Vegetarian only, dosas, some very spicy options, and (last I went) the best buffet out of the three.

Food at the Pheasant Lane Mall

Have some self-respect and stay hungry.

The Sublime

Sadly, nothing. I’ve tried to make this not very negative, which is why I’ve avoided mentioning a lot of places. Fact is the interesting food scene in Nashua is non-existent and seekers of truly transcendent meals must looks elsewhere. Even the decent options are under-used: MT’s doesn’t bother to open for lunch any more. I’m not sure who to blame for this, but the presence of more banks than restaurants might be a tell. At least in the case of Saffron Bistro which lost out to Ameriprise, which is kind of like a bank, except they specialize in scamming old people.

Originally I considered writing What to Eat near Nashua, but in doing so I’d hardly mention anything actually inside Nashua, so it was too depressing.

Rest in Peace, Cooking Matters and Saffron Bistro.


Addendum: “What about…”

Portland Pies has some interesting creations but the mushrooms seem canned and I swear they add sugar to pretend-caramelize their onions. The sausage you can get on the pizza is decent, considering other options. In the last six months they’ve been curiously terrible at assembling pizzas, with all of the toppings concentrated in the center.

How to Change Oneself

This is a short list of methods to help create and change behaviors, originally given to me in college by one of my professors in a philosophy class centered around contra-authoritarianism at RPI. Traits and motivations that you wish to develop can be consciously improved. Here are a few ways.

How to Change Oneself

Role Play (Fake It)

After identifying the behaviors you want to have, act as if you had them. Act the way that people with these habits tend to act.

It has been found, somewhat paradoxically, that inner psychological states and traits are best nurtured by outside behavior, not (solely) by internal commitment to develop them.

I hesitate to use the phrase “fake it” but it’s very common in this vein of advice (“Fake it ‘till you make it”). This is off-putting to some people, who deride the advice as engendering a counterfeit or phony personality. It’s important to remember you aren’t acting a certain way to be someone you can’t be. You’re acting a certain way to be the person you want to be in the near future.

You’re role-playing a future you, and it’s an important skill that people subconsciously practice their entire lives. Just as a young person cannot be called an adult until they act like an adult, you cannot have a behavior or trait until you first act like you do.

Be careful not to confuse actions that are habits with actions that are the result of habits. As the tech aphorism goes: acting like Steve Jobs does not make you any more like Steve Jobs, but working like Steve Jobs might.

Create Responsibility and Commit Publicly

Thanks to the social media firehose, this is easier than ever. Publicly commit to your resolution in front of people whose opinion matters to you — people who you’d hate to let down. Find others who will support and reinforce you in your attempts and goals.

Tell yourself that you are responsible for the decision and accountable for having made it, and the social powers of pride (and fear of shame!) will nudge you along.

Self-Reinforcement

Resolutions are made because the habits or goals look hard, and achieving them may be stressful. Whenever you succeed it’s important to reward yourself in your habits

Your rewards should not imitate the stereotypically comical “undo-button” style, such as gorging yourself on ice cream and fried foods after a few days of eating well.

Instead, you should try to think up unrelated awards, such as only watching the next episode of your favorite show after you’ve gone to the gym for the day. Turning this normal pleasure into a reward takes relatively little willpower, (in the worst-case you just don’t watch a show), and allows you to feel good for reinforcing something difficult you wanted to do.

Consider carefully all of the normal, small pleasures that you were going to do anyway that you can delay and schedule around (watching a show, playing a game, shopping, coffee, the beach, etc), and delay them until after you’ve done a resolution task. You will still do all these things, and look forward to them all the more while reinforcing your goals all the while.

Gradualism

Incremental goals are important. Small steps are the least daunting and the easiest to try. Generally, the more you can break down tasks into small chunks, the better off you will be.

A good example that uses both self-reinforcement and gradualism is the time management technique known as pomodoro, in which tasks are structured into short time blocks with planned breaks as rewards.

Find Like-Minded People

Start making acquaintances and hanging out with the sort of people you want to be like. Go to meetups in your area, and talk publicly about any new interests to see if any of your friends might share the same.

Role models are typically only talked about in the context of kids, but they’re important for everyone. Being around like-minded people constantly supplies one with examples that start working at the subconscious level, and provides a sense of normalcy for a lifestyle. Most of all it provides constant reinforcement for role-playing.


That’s it. No magic tricks, just several interconnected techniques to stay mindful of. I hope you find them useful. I’ll leave you with a bit of Longfellow:

We have not wings, we cannot soar;
But we have feet to scale and climb
By slow degrees, by more and more,
The cloudy summits of our time.

The mighty pyramids of stone
That wedge-like cleave the desert airs,
When nearer seen, and better known,
Are but gigantic flights of stairs.

The distant mountains, that uprear
Their solid bastions to the skies,
Are crossed by pathways, that appear
As we to higher levels rise.

The heights by great men reached and kept
Were not attained by sudden flight,
But they, while their companions slept,
Were toiling upward in the night.


From The Ladder of St. Augustine, by Henry Wadsworth Longfellow (poet most famous for The Midnight Ride of Paul Revere).

Letters to Recruiters (Or, Why I Love Recruiters)

This article is updated with new letters occasionally

HN likes to scorn recruiters (such as “Why I Hate Tech Recruiters”, or right now, Dear Google Recruiting…) Comments on these articles tend to agree upon the disdain.

Offhanded spam-campaigny emails are no fun but I don’t think it’s good reason to scorn the job. I love recruiters – A sincere effort from one I is its own kind of compliment. A compliment, no less, from a field that takes a serving of hostility and non-replies as their mid-day meal. The best recruiters brighten my day and the least I could do is be pleasant in return.

I get a “real” inquiry maybe about once a week (being from the mere hills of New Hampshire and notable for only one niche I find even this amount surprising) but I try to always take the time and give a reply. If the recruiter hasn’t shown much effort I copy and paste something suggesting that a more sincere letter would yield more sincere replies. If I don’t have the time, I can always delete the errant mail.

Being a good recruiter seems to involve the act of solving a problem that cannot be generalized well, and when we come across good recruiters we should do our part to reward them somehow, even if we aren’t interested in the position. If the recruiter has shown some effort then I feel obliged, time permitting, to give them something in return.

The replies I give are always a very roundabout way of declining but it gives me an opportunity to (hopefully) brighten the day of what I imagine is a difficult job that often involves a good deal of hostility and silence from the people they contact. I’d like to think recruiters have feelings, and if they spend the time to craft a sincere request then I will delightedly spend the time to craft at least a partially amusing reply.

How would you like it, after all, if you spend a day crafting thirty good recruiting emails only to be met with an empty (or hostile!) inbox the next morning?

Below are a couple of examples of the things I say in return. Names have been largely removed for the sake of privacy.


Dearest G-,

I apologize for the late reply. I have been working day and night (and dawn and dusk) as uncountable tasks approach my inbox (and life) in recent times.

While Microsoft is a fine company and I do enjoy my use of the Windows 8 release preview, I cannot accept any offers to apply because Redmond, Washington is very far from New Hampshire and I am the sort to walk to work.

I would perhaps urge you to suggest to the good Microsofters of Redmond to get out of their buildings and attempt to push them closer to New Hampshire but I do not think it is technically feasible, and besides they probably would not agree to do it, as backs would ache in even the best conditions, and New Hampshire is very far.

Perhaps someday I will choose to leave this small town but this year is not the year and so I must decline any offers for the time being.

Please take my kind regards, and the hope that the weather turns to more reasonable temperatures for the both of us,

Simon Sarris


Dearest K-,

Thank you for extending to me this invitation.

Unfortunately for perhaps both of us I live in New Hampshire and intend to remain in New Hampshire for the (metaphorically) foreseeable future. That is not a derision of Wisconsin, which I am sure is wonderful and produces many grand (or Epic) things and people. But while Wisconsin makes many fine and attractive things such as (say) cheeses (Sartori Bellavitano anyone?), trucks are always willing to relocate said cheeses to New Hampshire.

Trucks are less willing or able to move my house to Wisconsin, and even if they were, the Historical Society might raise an objection or two. Moving my friends would be even more difficult, as several of them object to being carried around and placed in other states.

Alas while there may come a time to lead myself from this Maple-syrup laden location, as Syrio says, “Not today.”

I hope your candidate search goes well,

Simon Sarris


S-,

Thank you for your invitation.

However I am comfortably employed (and living) in New Hampshire and do not intend to consider moving in the near future, regardless of that fact that your company and potential jobs may well be very interesting.

Or as our girlfriends of yore might have said, “It’s not you, it’s me.”

Your site is beautiful, by the way.

Hope for the best,

Simon Sarris


L. Sommerhalter,

Terribly sorry for the all-to-late reply. Work has kept me busy and a puppy has kept me busier still. Alas I’ve finally regained enough of an attention span to tackle my inbox.

Work keeps me happy and well-fed these days, so I have no reason to want to look for another job, though I imagine [company] is quite the lovely company to work for (as the Boston Business Journal assents). So sorry again to decline, but I must, as flattered as I am by your (professional) advances.

I hope you’re well. Stay warm,

Simon Sarris

(P.S. your name reads to me like “Summer halter”. Was it you who brought us all this snow?)


I’m sure not everyone is as easily flattered as I am by a piece of mail. But if we have a problem with the recruiting profession then we should probably find a better way to reward the good ones, shouldn’t we?

The Importance of GeoCities and Bob Ross

This month I turned a quarter-century old. I’ve finally finished writing the book that consumed the 24th year of my life, and now I’m left with time to think (and blog) again. This post is about identifying the most important quality that educational role models can have.

Any sufficiently advanced technology is indistinguishable from magic. – Arthur C. Clarke

When I was younger I used to look upon the scribbles created by trigonometry and calculus work, that to me seemed to incomprehensibly weave math and English together, and think to myself that there is simply no way I would ever be able to grasp the slightest bit of. It felt like a foregone conclusion that understanding such a series of symbols was a task that would always lie beyond my pea-sized brain.

The web felt the same way to me. Growing up I was fascinated with the discovery of every new site, but I could not begin to think of what might be involved in making one.

Creating anything with a computer, like doing calculus, was magic to be done by other people. I imagined creating websites was the serious and stuffy domain of adults who worked in tall glass buildings. It was probably expensive, and I bet you needed special equipment, maybe even contracts and lawyers. I couldn’t imagine just who developers might be (or even what they were called!), but I assumed some kind of suit-or-lab-coat-wearing professionals that only accomplished things in large teams after years of rigorous study.

My young pea-sized brain had no idea, but I assumed it sufficiently difficult that it wasn’t even worth asking anyone. Worse still, had I thought it worth asking, few or none of the adults in my life would have given me a sufficient answer. Many of them to this day must think about websites the way I did back then.

When I was 13, on a certain day in 2001 that’s difficult for Americans to forget, I joined a forum for the discussion of a video-game where you design and fight giant robots made up of several combined parts (Armored Core). The game isn’t important, but it is important that in the game there are billions of combinations of parts – more than enough to discuss (and argue!) the merits of different fighting robot designs.

Several members had little websites where they shared their designs and reasoning, and visiting them I stumbled across this place called geocities.com. This website told me that even if I knew nothing, they would let me make a website. For free.

Nobody told me that creating content on the web wasn’t magic, until the day I met GeoCities.

And so I made my first website. Of course it wasn’t how a professional would do it, GeoCities started you with a what-you-see-is-what-you-get editor, one that if we web developers had to use today we’d do so while crying into a gallon tub of ice cream, eating with our left hand and clicking away with our right.

But that’s not the point. GeoCities let kids like me go ahead and make something and put it up there. GeoCities gave me permission to make things I didn’t know I was allowed to make. I didn’t have my own house with my own address, but I had my own web site with its own address, something I could point my friends to and call my own.

The language I’m using is a bit curious, of course I didn’t actually need permission to make a website, but its important to note that for a lot of people, especially children, it is difficult for them to even begin exploring topics if they don’t know what goes into them.

Parents aren’t always much help. If you asked most of them how to make a movie that will be played in theaters they might tell you they have no idea, or else give you a list of things you’d need (script, director, cast, enormous sums of money, etc). Never-mind that the best answer for a child is “A camera, here’s the record button, I’d love to see what you can do.”

Television shows are largely no help to children either here, even the ones that detail how things are made tend to display the art of making things as a job best left to hyper-sophisticated machines and experts in lab coats.

We should celebrate anything and anyone that dispels the magic that professional (and to many, seemingly unapproachable) education is needed to do something. Bob Ross is another such example. He showed me (and many others) that oil painting is not something only done by Michelangelo-like professionals after decades of practice. It was something that could be accomplished – or much more importantly, started – by 9 year old me, even without lick of experience.

More to the point, I think it is extremely healthy to have the lowest bar possible to go from “Hey I like that” to “Can I do that? Can I make it myself?” And I think it is something that parents and teachers ought to have on their mind constantly.

There’s an issue with schools that a lot of people have and I’ve had a hard time articulating it myself until recently. We tend to agree that teaching mere facts and formulas alone constitutes an inadequate and dull school day.

GeoCities, Bob Ross and other great experiences like them point to a lesson: Schools, parents, and services need to always keep in mind that the primary goal of education is to expand a child’s scope of what is possible in this world. Even if there was just a single damn class where every day the teacher picked a random topic and said, “Did you know that to start making X all you need is Y? And Y is easy to get, and we can help you get it if that’s something you want to do.” This is what I’d like to see out of schools.

It doesn’t matter if a what-you-see-is-what-you-get editor is not how a professional would design websites. It doesn’t matter if a point-and-click camera is how a professional would shoot photos. Professionals like to deride these things, but I think they (and the instruction that comes along with them) tend to be the most important thing we’ve got in terms of education. Anything, anything to tell a child or newcomer that they can start making things today.

I don’t think this is a particularly tricky topic, but I think it’s easily overlooked. I think it matters that we show all newcomers the lowest possible bar to entry. There’s an art to making seemingly insurmountable things appear doable, and I think we should give it more attention.

As for me, now that I’ve stumbled back upon a few faint notions of free time, I’d like to help out on the web again. I used to fiendishly apply myself to StackOverflow, and I will return some brainpower to that task, but my real hope is to begin a Bob Ross-style video series about learning to program with JavaScript. JavaScript is a wonderful little language to start with, because everyone watching the video has all the tools they need to get started. Anyone running Chrome can press F12 and start typing statements into the console right away. The canvas element (the only thing I’m good at) now poses a great way for people to create little JavaScript programs quickly that involve visual results without bringing too much confusion into the picture (See: The DOM).

I’m optimistic about the video series, but I imagine it will be some time until it’s out. I had considered taking some time off work to do full-time work on nothing but these JavaScript tutorials/videos, updating the MDN, and holding office hours in StackOverflow chat. Be like a monk of the web. Alas I’ve not the cash for that just yet. But someday, maybe.

I hope I’ve articulated that well enough. Sorry it wasn’t shorter. My own brain feels muddled for all but poetry these days, so I’d like to leave you with a few verses of Longfellow, from The Ladder of St. Augustine:

The mighty pyramids of stone
That wedge-like cleave the desert airs,
When nearer seen, and better known,
Are but gigantic flights of stairs.

The distant mountains, that uprear
Their solid bastions to the skies,
Are crossed by pathways, that appear
As we to higher levels rise.

I want us to make pathways.

The Book is Complete

It’s been exactly one year since I began writing HTML5 Unleashed. I’m finally done everything, and it will be in stores next month. The Kindle edition is already available!

The book has all its code samples and images printed in full color. The text is packed with knowledge wrought from my HTML5 Canvas expertise (150+ pages on Canvas alone, including a multitude of common issues and little tricks gained from my work and my time on StackOverflow*). There are also separate chapters on Canvas interactivity and performance.

In the future I might write more about my experiences with the process. It’s been an interesting and exhausting year.

* I’ve been unable to answer much on StackOverflow during the last year but I’m still the only person to have a gold badge for Canvas and one of two people to have a gold badge for HTML5. A year ago I had answered more than 10% of all canvas questions ever asked on SO (its now at 7%). This is going on my resume under the heading “poor time management”!

Standard advice

Be positive.

Listen for 90% of a conversation and people will find you interesting.

Learn to ask engaging questions and let others do the answering. Don’t just ask people about facts, ask for their opinions too. Don’t be an interrogator. Be curious. Where were you before you were here?

Never criticize, condemn, or complain. Praise people a lot. Learn to spot good looks and compliment them.

Clean yourself up. Don’t skip showers. Care about how your hands and your hair look. Care about clothes. Care about as much as possible. Care about sports, care about elections, care about cars, care about how the sidewalk looks. Care about Rwanda and the Greek debt crisis. Care about backgammon and the nature of games. Never, ever expect anyone else to care.

Find out what they do care about and ask them about it. Try to care about that.

Don’t make every joke you could possibly make. A careful or clever observation will always be a better utterance than “that’s what she said.” Don’t use sarcasm. Strive for sincerity.

Don’t say every sentence that comes to your mind. Think signal to noise ratio. Say just enough to be interesting.

Don’t tell stories that aggrandize yourself. Never tell anyone how good you are at anything. I don’t care if you’re the best billiards player in the world. You can say “I like billiards” and that’s it. I’m serious. Never tell anyone how good you are. If you’re good, they’ll tell you. You can always let them see you in action, but never show off. Never expect a crowd. Be modest.

The person who says they like bowling and then bowls six strikes is more impressive than a person who claims to be amazing at bowling and then bowls ten strikes. Expectations mean a lot.

Understand more about where you live. Take your bike all over town. Ride to the end of the line. Walk around on foot. Look up reviews on every single restaurant even if you never go to them. Read the menus. Dine alone. Offer to go to breakfast together. Visit the city. Visit the country. Visit the mountains.

Spend a lot of time at the ocean-side. Run around on the beach like an idiot. Run around in the waves. Swim until you’ve dreamed too much about what’s below the ocean. Build a trench, be a soldier. Build castles, be a king. Watch how easily the castle fades away if you don’t protect it. Think of your investments, metaphorical or not. Remember Borges:

“Nothing is built on stone; all is built on sand, but we must build as if the sand were stone.”

Many things wash away naturally, you should allow the same. Forgive often.

Realize that you gain nothing from being shy. That doesn’t mean you have to start making speeches in front of crowds. It means you have to be as open and honest as you plainly can be. There’s nothing wrong with emotions and there’s nothing wrong with telling people how you feel about something. No one can ever contest how you feel. Being an open book may sound like a vulnerable position to be in, but it is the exact opposite.

Spend money on experiences and not things. Read more books. Have what she’s having. Make things, always make things, physical things, even if its just paper cranes and home-cooked meals. Create and share. Understand that most people won’t give a damn. That’s okay. Always create. Enjoy the beauty of it.

Move to a not-suburb. Join meetup.com or grubwithus.com or whatever is in the paper. Knitting clubs aren’t about knitting, they are about socializing. Take pottery/archery/tennis/anything classes. Join a club soccer team. Visit the same cafe at least once a week. Jog through the park. Smile at everyone. Literally put yourself out there. Be discover-able. Be friendly.

Be positive.

In short, remember: Smile, eyes, build, butt. Be happy. Be sincere. Take care of yourself. Dress well.

I'm writing a book!

I’m writing a book!

On HTML5!

You can preorder it on Amazon here.

It will be in full color with plenty of examples and syntax highlighting and in real live bookstores. A large part of the book will be canvas, of course, and I plan for all chapters and subjects to be independent of each-other in case you wish to pick and choose the parts of HTML5 you read about.

Signing the contract means signing away a good chunk of my free time, though, so there may not be any new posts for a while. I’ll still try to squeeze in a blog post here and there, as there have been a lot of very interesting cases I’ve come across helping people with canvas lately.

It’s been a very interesting past two years. I’m now the top answerer for both Canvas and HTML5 on Stack Overflow. I hope I can find the time to continue helping people while I write. And I do try give a thoughtful reply to every question emailed to me, even if it takes some time to respond!


If you want to read my minor thoughts and updates and programming humor in the meantime there is always my Twitter.

That’s all for now!

A Gentle Introduction to Making HTML5 Canvas Interactive

I wrote a book on HTML5, including three chapters on Canvas! Buy it here.

This is a big overhaul of one of my tutorials on making and moving shapes on an HTML5 Canvas. This new tutorial is vastly cleaner than my old one, but if you still want to see that one or are looking for the concept of a “ghost context” you can find that one here.

This tutorial will show you how to create a simple data structure for shapes on an HTML5 canvas and how to have them be selectable. The finished canvas will look like this:


This text is displayed if your browser does not support HTML5 Canvas.

Click to drag the shapes. Double click to add a new shape.

We’ll be going over a few things that are essential to interactive apps such as games (drawing loop, hit testing), and in later tutorials I will probably turn this example into a small game of some kind. The code also contains simple examples of using JavaScript prototypes and closures. I will try to accommodate JavaScript beginners but this introduction does expect at least a rudimentary understanding of JS. Not every piece of code is explained in the text, but almost every piece of code is thoroughly commented!

The HTML5 Canvas

A Canvas is made by using the <canvas> tag in HTML:

<canvas id="canvas" width="400" height="300">
    This text is displayed if your browser does not support HTML5 Canvas.
   </canvas>

A canvas isn’t smart: it’s just a place for drawing pixels. If you ask it to draw something it will execute the drawing command and then immediately forget everything about what it has just drawn. This is sometimes referred to as an immediate drawing surface, as contrasted with SVG as a retained drawing surface, since SVG keeps a reference to everything drawn. Because we have no such references, we have to keep track ourselves of all the things we want to draw (and re-draw) each frame.

Canvas also has no built-in way of dealing with animation. If you want to make something that you’ve drawn move, you have to clear the entire canvas and redraw all of the objects with one or more of them in a new location. And you have to do it often, of course, if you want a semblance of animation or motion.

So we’ll need to add:

  1. Code for keeping track of objects
  2. Code for keeping track of canvas state
  3. Code for mouse events
  4. Code for drawing the objects as they are made and move around

The things we draw

To keep things simple for this example we will start with a Shape class to represent rectangular objects.

JavaScript doesn’t technically have classes, but that isn’t a problem because JavaScript programmers are very good at playing pretend. Functionally (well, for our example) we are going to have a Shape class and create Shape instances with it. What we are really doing is defining a function named Shape and adding functions to Shape’s prototype. You can make new instances of the function Shape and all instances will share the functions defined on Shape’s prototype.

If you’ve never encountered prototypes in JavaScript before or if the above sounds confusing to you, I highly recommend reading Crockford’s JavaScript: The Good Parts. The book is an intermediate overview of JavaScript that gives a good understanding of why programmers choose to create objects in different ways, why certain conventions are frowned upon, and just what makes JavaScript so different.

Here’s our Shape constructor and one of the two prototype methods, which are comparable to a class instance methods:

// Constructor for Shape objects to hold data for all drawn objects.
// For now they will just be defined as rectangles.
function Shape(x, y, w, h, fill) {
  // This is a very simple and unsafe constructor.
  // All we're doing is checking if the values exist.
  // "x || 0" just means "if there is a value for x, use that. Otherwise use 0."
  this.x = x || 0;
  this.y = y || 0;
  this.w = w || 1;
  this.h = h || 1;
  this.fill = fill || '#AAAAAA';
}

// Draws this shape to a given context
Shape.prototype.draw = function(ctx) {
  ctx.fillStyle = this.fill;
  ctx.fillRect(this.x, this.y, this.w, this.h);
}

They are pretty self-explanatory. The shape constructor has “defaults” if you give it no arguments, and calling draw on a shape will set the fill and draw a rectangle on the given context corresponding to the measurements of the Shape.

Keeping track of canvas state

We’re going to have a second class (function) called CanvasState. We’re only going to make one instance of this function and it will hold all of the state in this tutorial that is not associated with Shapes themselves.

CanvasState is going to foremost need a reference to the Canvas and a few other field for convenience. We’re also going to compute and save the border and padding (if there is any) so that we can get accurate mouse coordinates.

In the CanvasState constructor we will also have a collection of state relating to the objects on the canvas and the current status of dragging. We’ll make an array of shapes to keep track of whats been drawn so far, a flag “dragging” that will be true while we are dragging, a field to keep track of which object is selected and a “valid” flag that will be set to false will cause the Canvas to clear everything and redraw.

I’m going to add a bunch of variables for keeping track of the drawing and mouse state. I already added shapes[] to keep track of each object, but we’ll also need a var for the canvas, the canvas’ 2d context (where all drawing is done), whether the mouse is dragging, width/height of the canvas, and so on.

function CanvasState(canvas) {

  // ...

  // I removed some setup code to save space
  // See the full source at the end


  // **** Keep track of state! ****

  this.valid = false; // when set to true, the canvas will redraw everything
  this.shapes = [];  // the collection of things to be drawn
  this.dragging = false; // Keep track of when we are dragging
  // the current selected object.
  // In the future we could turn this into an array for multiple selection
  this.selection = null;
  this.dragoffx = 0; // See mousedown and mousemove events for explanation
  this.dragoffy = 0;

Mouse events

We’ll add events for mousedown, mouseup, and mousemove that will control when an object starts and stops dragging. We’ll also disable the selectstart event, which stops double-clicking on canvas from accidentally selecting text on the page. Finally we’ll add a double-click (dblclick) event that will create a new Shape and add it to the CanvasState’s list of shapes.

The mousedown event begins by calling getMouse on our CanvasState to return the x and y position of the mouse. We then iterate through the list of Shapes to see if any of them contain the mouse position. We go through them backwards because they are drawn forwards, and we want to select the one that appears topmost, so we must find the potential shape that was drawn last.

If we find a shape then we want to select it. We save the offset, save a reference to that shape as the CanvasState’s this.selection, set this.dragging to true and set the this.valid flag to false. Already we’ve used most of our state! Finally if we didn’t find any objects we need to see if there was a selection saved from last time. Since we clicked on nothing, we obviously didn’t click on the already-selected object, so we want to “deselect” and clear the selection reference. Clearing the selection means we will have to clear the canvas and redraw everything without the selection ring, so we set the valid flag to false.


  // ...
  // (We are still in the CanvasState constructor)

  // This is an example of a closure!
  // Right here "this" means the CanvasState. But we are making events on the Canvas itself,
  // and when the events are fired on the canvas the variable "this" is going to mean the canvas!
  // Since we still want to use this particular CanvasState in the events we have to save a reference to it.
  // This is our reference!
  var myState = this;

  //fixes a problem where double clicking causes text to get selected on the canvas
  canvas.addEventListener('selectstart', function(e) { e.preventDefault(); return false; }, false);
  // Up, down, and move are for dragging
  canvas.addEventListener('mousedown', function(e) {
    var mouse = myState.getMouse(e);
    var mx = mouse.x;
    var my = mouse.y;
    var shapes = myState.shapes;
    var l = shapes.length;
    for (var i = l-1; i >= 0; i--) {
      if (shapes[i].contains(mx, my)) {
        var mySel = shapes[i];
        // Keep track of where in the object we clicked
        // so we can move it smoothly (see mousemove)
        myState.dragoffx = mx - mySel.x;
        myState.dragoffy = my - mySel.y;
        myState.dragging = true;
        myState.selection = mySel;
        myState.valid = false;
        return;
      }
    }
    // havent returned means we have failed to select anything.
    // If there was an object selected, we deselect it
    if (myState.selection) {
      myState.selection = null;
      myState.valid = false; // Need to clear the old selection border
    }
  }, true);

The mousemove event checks to see if we have set the dragging flag to true. If we have it gets the current mouse positon and moves the selected object to that position, remembering the offset of where we were grabbing it. If the dragging flag is false the mousemove event does nothing.

  canvas.addEventListener('mousemove', function(e) {
    if (myState.dragging){
      var mouse = myState.getMouse(e);
      // We don't want to drag the object by its top-left corner,
      // we want to drag from where we clicked.
      // Thats why we saved the offset and use it here
      myState.selection.x = mouse.x - myState.dragoffx;
      myState.selection.y = mouse.y - myState.dragoffy;
      myState.valid = false; // Something's dragging so we must redraw
    }
  }, true);

The mouseup event is simple, all it has to do is update the CanvasState so that we are no longer dragging! So once you lift the mouse, the mousemove event is back to doing nothing.

canvas.addEventListener('mouseup', function(e) {
    myState.dragging = false;
  }, true);

The dblclick event we’ll use to add more Shapes to our canvas. It calls addShape on the CanvasState with a new instance of Shape. all addShape does is add the argument to the list of Shapes in the CanvasState.

// double click for making new Shapes
  canvas.addEventListener('dblclick', function(e) {
    var mouse = myState.getMouse(e);
    myState.addShape(new Shape(mouse.x - 10, mouse.y - 10, 20, 20,
                               'rgba(0,255,0,.6)'));
  }, true);

There are a few options I implemented, what the selection ring looks like and how often we redraw. setInterval simply calls our CanvasState’s draw method. Our interval of 30 means that we call the draw method every 30 milliseconds.

// **** Options! ****

  this.selectionColor = '#CC0000';
  this.selectionWidth = 2;
  this.interval = 30;
  setInterval(function() { myState.draw(); }, myState.interval);
}

Drawing

Now we’re set up to draw every 30 milliseconds, which will allow us to continuously update the canvas so it appears like the shapes we drag are smoothly moving around. However, drawing doesn’t just mean drawing the shapes over and over; we also have to clear the canvas on every draw. If we don’t clear it, dragging will look like the shape is making a solid line because none of the old shape-positions will go away.

Because of this, we clear the entire canvas before each Draw frame. This can get expensive, and we only want to draw if something has actually changed within our framework, which is why we have the “valid” flag in our CanvasState.

After everything is drawn the draw method will set the valid flag to true. Then, once we do something like adding a new Shape or trying to drag a Shape, the state will get invalidated and draw() will clear, redraw all objects, and set the valid flag again.

// While draw is called as often as the INTERVAL variable demands,
// It only ever does something if the canvas gets invalidated by our code
CanvasState.prototype.draw = function() {
  // if our state is invalid, redraw and validate!
  if (!this.valid) {
    var ctx = this.ctx;
    var shapes = this.shapes;
    this.clear();

    // ** Add stuff you want drawn in the background all the time here **

    // draw all shapes
    var l = shapes.length;
    for (var i = 0; i < l; i++) {
      var shape = shapes[i];
      // We can skip the drawing of elements that have moved off the screen:
      if (shape.x > this.width || shape.y > this.height ||
          shape.x + shape.w < 0 || shape.y + shape.h < 0) continue;
      shapes[i].draw(ctx);
    }

    // draw selection
    // right now this is just a stroke along the edge of the selected Shape
    if (this.selection != null) {
      ctx.strokeStyle = this.selectionColor;
      ctx.lineWidth = this.selectionWidth;
      var mySel = this.selection;
      ctx.strokeRect(mySel.x,mySel.y,mySel.w,mySel.h);
    }

    // ** Add stuff you want drawn on top all the time here **

    this.valid = true;
  }
}

We go through all of shapes[] and draw each one in order. This will give the nice appearance of later shapes looking as if they are on top of earlier shapes. After all the shapes are drawn, a selection handle (if there is a selection) gets drawn around the shape that this.selection references.

If you wanted a background (like a city) or a foreground (like clouds), one way to add them is to put them before or after the main two drawing bits. There are often better ways though, like using multiple canvases or a CSS background-image, but we won’t go over that here.

Getting mouse coordinates on Canvas

Getting good mouse coordinates is a little tricky on Canvas. You could use offsetX/Y and LayerX/Y, but LayerX/Y is deprecated in webkit (Chrome and Safari) and Firefox does not have offsetX/Y.

The most bulletproof way to get the correct mouse position is shown below. You have to walk up the tree adding the offsets together. Then you must add any padding or border to the offset. Finally, to fix coordinate problems when you have fixed-position elements on the page (like the wordpress admin bar or a stumbleupon bar) you must add the <html>’s offsetTop and offsetLeft.

Then you simply subtract that offset from the e.pageX/Y values and you’ll get perfect coordinates in almost every possible situation.

// Creates an object with x and y defined,
// set to the mouse position relative to the state's canvas
// If you wanna be super-correct this can be tricky,
// we have to worry about padding and borders
CanvasState.prototype.getMouse = function(e) {
  var element = this.canvas, offsetX = 0, offsetY = 0, mx, my;

  // Compute the total offset
  if (element.offsetParent !== undefined) {
    do {
      offsetX += element.offsetLeft;
      offsetY += element.offsetTop;
    } while ((element = element.offsetParent));
  }

  // Add padding and border style widths to offset
  // Also add the offsets in case there's a position:fixed bar
  offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft;
  offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop;

  mx = e.pageX - offsetX;
  my = e.pageY - offsetY;

  // We return a simple javascript object (a hash) with x and y defined
  return {x: mx, y: my};
}

At long last

From here its just a few lines to draw some shapes to move around. We make one instance of CanvasState, passing it a reference to the canvas we want to use, then we can add any number of new shapes to it. The code below produces the example at the top of this page:

var s = new CanvasState(document.getElementById('canvas1'));
s.addShape(new Shape(40,40,50,50)); // The default is gray
s.addShape(new Shape(60,140,40,60, 'lightskyblue'));
// Lets make some partially transparent
s.addShape(new Shape(80,150,60,30, 'rgba(127, 255, 212, .5)'));
s.addShape(new Shape(125,80,30,80, 'rgba(245, 222, 179, .7)'));

There are a few little methods I added that are not shown, such as Shape’s method to see if a point is inside its bounds. You can see and download the full demo source here.

Now that we have a basic structure down, it is easy to write code that handles more complex shapes, like paths or images or video. Rotation and scaling these things takes a bit more work, but is quite doable with the Canvas and our selection method is already set up to deal with them.

If you would like to see this code enhanced in future posts (or have any fixes), let me know.

I wrote a book on HTML5, including three chapters on Canvas! Buy it here.

The most amazing thing

I live my life in a state of constant, quiet amazement. Almost everything is impressive to me, from the last book I read to the last soup I ate. I don’t get bored, and am often happy to just sit and think about things, pretty much any thing.

It’s just reached midnight in New Hampshire, and “yesterday” the Galaxy Nexus was released for Verizon in the United States.

I’m sure to lots of people this is just yet-another-android-phone. Or for many its simply an upgrade from one gadget to the next. People will yawn, or fawn, or get on with their lives with or without it. I myself would probably be pleased as Punch with just about any modern smartphone.

Yesterday I bought a Galaxy Nexus, my first smartphone and second-ever cellphone.

Learning to set my alarm for tomorrow morning, I find myself reflecting. I really am completely in awe. Starstruck. I am a computer person, and here is a thing more powerful than most of the computers I have ever owned.

In New Hampshire 4G was rolled out Wednesday or so my coworkers tell me. The data capabilities of the phone are impressive to me, but then again 56k speeds on the phone would not be any less impressive. How could they be?

Somehow I have made it almost to 2012 without owning a GPS or an MP3 player or a pocket camera. It’s not that I’m against them, I just never found much need. Now I have a device with a scope and power so large I cannot believe it is this small.

The age of “wondering why” is over. This is instant portable access to the largest knowledge and communication infrastructure in the world. A rough approximation of the sum of human knowledge is literally carried along in my pocket. I can express and communicate and learn from anywhere. At my desk, in my bed, on the road, in the woods.

How is this not the most amazing thing?

Understanding the HTML5 Canvas image security rules

There’s a common point of confusion regarding when one can use HTML5 Canvas getImageData() and toDataUrl() methods. Certain canvas conditions will cause these methods to throw a security error.

The rules for what one can and cannot do are laid out in the Canvas specification, though the reasoning behind them isn’t so obvious. The most typical violation is when a programmer calls ctx.drawImage() with an image that is from a different domain (than the page that the canvas is on) or an image that is on the local file system. When ctx.drawImage() is used in one of these two ways, the canvas internally sets its origin-clean flag to false.

From the moment a canvas has its origin-clean flag set to false, the getImageData() and toDataUrl() methods will throw security errors. There are a few less common cases where the origin-clean flag will be set to false, you can read about them in the spec here.

The reason for this security is to prevent something called information leakage. To see why this is a security issue, consider the following hypothetical situation:

Say you are on a work network and so you have access to internal, private company sites and your (private!) hard-drive. The private sites might be something like www.internal.myCompany.com and your hard drive would be accessible from urls like file:///C:/SomeOfMyPhotos/.

Now suppose you visited a website with a hidden canvas and while you were browsing the site that canvas was constantly calling drawImage() onto that canvas with urls that it was guessing might exist. These urls would be things like an image on the private subdomain:

www.internal.myCompany.com/secret/secret-plans.jpg

Or an image on your hard drive:

file:///C:/SomeOfMyPhotos/thatEmbarassingPhoto.png

The malicious site could keep trying different combinations of private-to-you urls until it found one that was actually a file. Then it would draw it to the canvas. Then it would get the imageData from the canvas and send it off to the server.

Voila! The malicious site owner now has your secret plans and your embarrassing photos, much without your consent.

Now we know that the above scenario is not very probable: In the real world, secret plans are almost always in PNG format whereas embarassing photos are almost universally in JPG format! But it stands that situations like the above could happen and so the security implications of canvas must take this into account.

I wrote a book on HTML5, including three chapters on Canvas! Buy it here.