Theory Time, Housing Market Edition

I’ve been writing slightly more lately. This blog will continue to have small posts, mostly just thinking out loud.

More structured writings may be over at medium. My profile here.

Theory Time, Housing Market Edition?

(this isn’t the first)

Growth in home values is practically the entire source of increased r in Piketty’s r > g.

It is therefore more or less true that “home ownership is the greatest builder of personal wealth”, and if you turn off your brain there it might sound like a good thing. It can be very true and still be at the expense of everybody else in society. Home owners “feel” rich because they are sitting on expensive assets, but they’d have to sell it to buy another one, and look what happens when their assets suddenly turn to worthless (See: Flint Michigan).
These numbers are made up, just to illustrate:

Imagine saving up money to buy a home for 50K and seeing it appreciate to 200K. Yay you’ve made quite the paper profit. Or not, because when you sell it, to buy any comparable house will also cost 200K, so it’s a wash. Unless you live in Flint, then your house went from 50K to 200K and then to 0K, time to start over. And when you start over the next house you buy still costs 200K. Maybe you’re not so happy now that home prices appreciated after all, you’d be better off if the houses still all cost 50K. Saving up this time won’t be as easy!

The people in Flint are actively harmed, because mobility across the US is limited as long as your personal worth is tied to the fate of your house.
The people in Flint also serve as a good proxy for almost all young people. Millenials & younger had no assets to appreciate all the while, so the first house they want to buy costs 200K, instead of 50K, so they never buy one.

In other words, “home ownership is the greatest builder of personal wealth”, of one generation at the expense of the next. Inflating the value of these assets helps the early-comers and people who never have any disaster strike, but its at the expense of late-comers, people who “lose” their house to disaster or circumstance, etc.

Maybe there was a better alternative to subsidizing home ownership.
These are not personal gripes, just observations. The subsidized home ownership rules will probably benefit me a lot, but I’d gladly vote against my own interests here for the interests of my generation. (One of the reasons I hate when people say “why do they vote against their own interests?” aren’t there a million reasons?)

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 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 dangling 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. Pressed’s food is the most interesting in Nashua for breakfast and lunch. Try the Medusa or Shakshuka. The Zohan and Sabich are also fantastic.

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.) Right now the menu at MT’s is pretty good and its easily the best restaurant downtown (or Surf if you like fish).

At both MT’s and Buckey’s the burgers are made from steak trimmings and are the best in the area. At MT’s get the Tournedos (Actually most of the Summer 2017 menu is great). 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 where 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 quite good, Filho’s Cucina in Groton is another nice Italian spot.

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

Bedford has a few fancy places that I’m on the fence about including. I’m sure you know the names. Portsmouth, obviously, is the capital of good fancy food in New Hampshire, but now we’re getting quite far.

 

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 under-rated 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 is an excellent and more authentic version of Chipotle run by great people. It’s my default for a no-frills lunch.

The only 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 Buckley’s 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.

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.

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.

A transformation class for Canvas to keep track of the transformation matrix

I’m writing a book on HTML5, including Canvas! Click here for more information.

The HTML5 Canvas does not have a method for getting the current transformation matrix. For some applications, keeping track of the current transformation matrix would be a nice feature to have.

I’ve made this easier by creating a simple Transform class for use with Canvas. You can have a look at it here.

It has all of the Canvas equivalents, and can be used alongside canvas to record the matrix state or can be used instead of and then applied to the canvas.

In other words, a start-to-finish use of the Transform would be like this:

var t = new Transform();
t.rotate(5);
var m = t.m;
ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);

Which will do the exact same thing as this:

ctx.rotate(5);

Or the shorter:

var t = new Transform();
t.rotate(5);
ctx.rotate(5);

But of course allow you to keep track of it!

If you wanted, you could easily call the class to take a context and always do the operations when it is called.

Increasing Performance by Caching Paths on HTML5 Canvas

I’m writing a book on HTML5, including Canvas! Click here for more information.

Much of the functionality of Canvas comes from its path drawing functions. Unfortunately for game designers and animators, re-drawing paths over and over can amount to a tangible performance hit. To increase performance, let’s take a look at caching paths as images to avoid redrawing them traditionally.


Paget holmes
Gentlemen waiting for a path to finish rendering

First we need to ensure that caching a path will actually lead to a performance increase. We can devise a simple test for this using JSPerf. We need a path to test, so let’s write something fairly simple.

ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.lineWidth = 4;
ctx.moveTo(10,10);
ctx.lineTo(10,30);
ctx.lineTo(30,30);
ctx.lineTo(40,70);
ctx.quadraticCurveTo(72,43,22,12);
ctx.quadraticCurveTo(12,43,12,102);
ctx.stroke();

This does not produce a particularly complex or exciting path:



But it will do.

The thing we want to ponder here is whether redrawing this path, in other words executing every one of the instructions needed to make the path, will be a slower process than if we cached it. We can achieve caching by drawing the path from these instructions only once, to an in-memory canvas, and then using drawImage from our in-memory canvas onto our real canvas to redraw the path.

That isn’t the only way to cache. We could instead draw it to a canvas and then make a PNG out of it, and call drawImage from that PNG instead, but for the sake of making a simpler test we will stick with using an in-memory canvas.

So let us take all of the drawing instructions above and execute them on the in-memory canvas. Then in our draw loop, instead of drawing out the path every time, we simply draw the in-memory canvas to our real canvas:

// can2 is our in-memory canvas
ctx.drawImage(can2, 0, 0);

The test is simple enough. Giving it a go, the results are immediately clear: pre-rendering and using drawImage is more than ten times as fast as drawing the path, even for the relatively simple path used!



The more complex the path, the more time you will save with caching. If you’re using a lot of complex paths to render shapes, such an optimization ought to speed up your draw loop by a great deal. The JSPerf page shows a simple setup if you want to make the test for yourself.

Other considerations

Pre-rendering paths isn’t a magic bullet, there are still a lot of uses for drawing paths constantly in canvas. If you are making a live drawing application, or otherwise constructing dynamic paths and/or moving and animating paths on the fly, then any kind of pre-rendering is going to be nearly pointless or even harmful to performance. After all, what’s the use of drawing something to a separate canvas and drawing that state back to the original canvas if the path changes constantly? You’d need to re-draw the in-memory canvas just as often, so you’d lose all benefit.

It is also worth mentioning that you might want to play around with using PNGs instead of in-memory canvases. Another thing to test is putting multiple paths onto one in-memory canvas versus putting them all in their own separate canvases, effectively making a sprite sheet. From previous tests, it seems that there is a slight advantage to giving each sprite its own png instead of using a single-png (or single in-memory canvas) sprite-sheet, but it wasn’t that big of a difference.

If you do choose to use a sprite sheet, note that there are a lot of decent tools out there for compressing and organizing them, such as Sprite Sheet Packer.

Selectable Shapes Part 2: Resizable, Movable Shapes on HTML5 Canvas

Wait! This tutorial is rather old and I’ve given part one a major overhaul. You should really read (or at least start with) the new one here instead.

In the first tutorial I showed how to create a basic data structure for shapes on an HTML5 canvas and how to make them selectable, draggable, and movable. In this second part we’ll be reorganizing the code a little bit and adding selection handles so we can resize our Canvas objects.

The finished canvas will look like this:


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

Click to select a box. Click on a selection handle to resize. Double click to add new boxes.


This article’s code is written primarily to be easy to understand. It isn’t optimized for performance because a little bit of the drawing is set up so that more complex shapes can easily be added in the future.

In this tutorial we will add:

  1. Code for drawing the eight boxes that make up the selection handles
  2. Some small adjustments to the draw code
  3. Code to be run on every mouse move event
  4. Code for changing the mouse cursor when it is over a selection handle
  5. Code for resizing

Drawing the selection handles

The eight selection handles are unique in that each one allows you to resize an object in a different way. For instance clicking on the top-middle one will only let you make it taller or shorter, but the top-right one will allow you to make it taller, shorter, as well as more wide or narrow.

Like all decidedly unique things, we’ll want to keep track of them.

// New, holds the 8 tiny boxes that will be our selection handles
// the selection handles will be in this order:
// 0  1  2
// 3     4
// 5  6  7
var selectionHandles = [];

Previously we had the variables mySelColor and mySelWidth for the selection’s color and width. Now we also add variables for selection box color and size:

var mySelBoxColor = 'darkred'; // New for selection boxes
var mySelBoxSize = 6;

Draw’s new home

Draw is still its own function but most of the code has been moved out of it. We’re going to make our Box class start to look a little more classy by letting boxes draw themselves. If you haven’t seen this syntax before, it adds the draw function to all instances of the Box class, creating a someBox.draw() we can call on boxes. To clear up confusion, our old draw loop will be renamed mainDraw.

// New methods on the Box class
Box.prototype = {
  // we used to have a solo draw function
  // but now each box is responsible for its own drawing
  // draw() will call this with the normal canvas
  // myDown will call this with the ghost canvas with 'black'
  draw: function(context, optionalColor) {
    // ... (draw code) ...
  } // end draw

}

This draw code is lifted from the old draw method but with a few additions for the selection handles. We check to see if the current box is selected, and if it is, we draw the selection outline as well as the eight selection boxes, their places based on the selected object’s bounds.

In the Init() function we need to add the selectionHandles[] initialization as well as a new event. In the past, myMove was only activated if you pressed down with the mouse, and became deactivated as soon as the mouse was released. Now we need myMove to be active all the time.

// new code in init()
canvas.onmousemove = myMove;

// set up the selection handle boxes
for (var i = 0; i < 8; i ++) {
  var rect = new Box;
  selectionHandles.push(rect);
}

Our new main draw loop is now very slimmed down:

function mainDraw() {
  if (canvasValid == false) {
    clear(ctx);
    
    // draw all boxes
    var l = boxes.length;
    for (var i = 0; i < l; i++) {
      boxes[i].draw(ctx); // we used to call drawshape, but now each box draws itself
    }
    
    canvasValid = true;
  }
}

Doing this reorganization isn't too important now, but it will be useful later on if we have many different types of objects draw themselves. After all, rectangles and (for instance) lines are not drawn in the same way, so if we can put all the custom drawing code in the object's own class we can keep things better organized.

myMove revisited

Before I talk about myMove lets take a look at two new variables added to the top of our code that signal whether or not a box is being dragged and if so, from which selection handle.

var isResizeDrag = false;
var expectResize = -1; // New, will save the # of the selection handle if the mouse is over one.

isResizeDrag seems simple enough, it works almost identically to isDrag. expectResize will be a number between 0 and 7 to indicate which selection handle is currently active. If none is active (the default), we'll set it to -1.

In most programs that have selection handles (such as the edges of your browser) it is nice to have the mouse cursor change to show that an action can be performed. To do this we are going to have to ask where the mouse is located all the time and see if it is over one of our eight selection handles. Remember that above we made myMove active all of the time and Now we have to add code to it:

// Happens when the mouse is moving inside the canvas
function myMove(e){
  if (isDrag) {
    getMouse(e);
    
    mySel.x = mx - offsetx;
    mySel.y = my - offsety;   
    
    // something is changing position so we better invalidate the canvas!
    invalidate();
  } else if (isResizeDrag) {
    // ... new code to talk about later.
  }
  getMouse(e);
  // if there's a selection see if we grabbed one of the selection handles
  if (mySel !== null && !isResizeDrag) {
    for (var i = 0; i < 8; i++) {
      // 0  1  2
      // 3     4
      // 5  6  7
      
      var cur = selectionHandles[i];
      
      // we dont need to use the ghost context because
      // selection handles will always be rectangles
      if (mx >= cur.x && mx <= cur.x + mySelBoxSize &&
          my >= cur.y && my <= cur.y + mySelBoxSize) {
        // we found one!
        expectResize = i;
        invalidate();
        
        switch (i) {
          case 0:
            this.style.cursor='nw-resize';
            break;
          case 1:
            this.style.cursor='n-resize';
            break;
          case 2:
            this.style.cursor='ne-resize';
            break;
          case 3:
            this.style.cursor='w-resize';
            break;
          case 4:
            this.style.cursor='e-resize';
            break;
          case 5:
            this.style.cursor='sw-resize';
            break;
          case 6:
            this.style.cursor='s-resize';
            break;
          case 7:
            this.style.cursor='se-resize';
            break;
        }
        return;
      }
      
    }
    // not over a selection box, return to normal
    isResizeDrag = false;
    expectResize = -1;
    this.style.cursor='auto';
  }

So if there is something selected and we are not already dragging, we will execute some code to see if the mouse position is over one of the selection boxes. If it is, give the mouse cursor the correct arrow. If the mouse isn't over a selection box, make sure we change it back to the normal pointer.

You'll also notice that at the start, after "if (isDrag)" we have a new test, "else if (isResizeDrag)." isResizeDrag becomes true if two conditions are met:

  1. expectResize is set to one of the selection handle numbers (is not -1)
  2. we have pressed down the mouse

In other words, it only happens if the mouse is over a selection handle and has been pressed. We add a tiny bit of code to myDown to make this work.

// Happens when the mouse is clicked in the canvas
function myDown(e){
  getMouse(e);
  
  //we are over a selection box
  if (expectResize !== -1) {
    isResizeDrag = true;
    return;
  }

  // ... the rest of myDown

}

Anyway, getting back to myMove. We are looking for the "else if (isResizeDrag)" to see what happens when this is true.

function myMove(e){
  if (isDrag) {
    
    // ...

  } else if (isResizeDrag) {
    // time ro resize!
    var oldx = mySel.x;
    var oldy = mySel.y;
    
    // 0  1  2
    // 3     4
    // 5  6  7
    switch (expectResize) {
      case 0:
        mySel.x = mx;
        mySel.y = my;
        mySel.w += oldx - mx;
        mySel.h += oldy - my;
        break;
      case 1:
        mySel.y = my;
        mySel.h += oldy - my;
        break;
      case 2:
        mySel.y = my;
        mySel.w = mx - oldx;
        mySel.h += oldy - my;
        break;
      case 3:
        mySel.x = mx;
        mySel.w += oldx - mx;
        break;
      case 4:
        mySel.w = mx - oldx;
        break;
      case 5:
        mySel.x = mx;
        mySel.w += oldx - mx;
        mySel.h = my - oldy;
        break;
      case 6:
        mySel.h = my - oldy;
        break;
      case 7:
        mySel.w = mx - oldx;
        mySel.h = my - oldy;
        break;
    }
    
    invalidate();
  }
  
  // ... rest of myMove
}

We see a bunch of arithmetic dealing with precisely how each handle will resize the box. Handle #6 is middle-bottom, so it only resizes the height of the box. Handle #1, on the other hand, is the middle top. It has to resize both the Y-axis co-ordinate as well as the height. If #1 only changed the Y-axis, then dragging it upwards would just look like the entire box is being dragged upwards. If it just resized the height, the top of the box would stay in the same position and we certainly don't want that if the top is what we intended to move!

That's pretty much everything. Try it out yourself above or see the demo and download the full source on this page.

So that wasn't too bad. A few long chunks were added but not because of complexity, just because each of the eight selection handles is uniquely placed and does a unique resizing task.

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

Making and Moving Selectable Shapes on an HTML5 Canvas: A Simple Example

I’m writing a book on HTML5, including Canvas! Click here for more information.

Wait! I’ve given this tutorial a major overhaul and you should really read the new one here instead.

This is part one in a series. Part 2 can be found 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 boxes. Double click to add new boxes.


This article’s code is written primarily to be easy to understand. It isn’t optimized for performance, though a little bit of the drawing is set up so that more complex shapes can easily be added in the future.

We’ll be going over a few things that are also essential to game-development (drawing loop, hit testing), and in later tutorials I will probably turn this example into a small game.

The HTML5 Canvas

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

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

A canvas isn’t smart: it’s just a place for drawing pixels. If you ask it to draw something it will do so and then immediately forget everything about what you have just done. Because of this we have to keep track ourselves of all the things we want to draw (and re-draw) each frame.

So we’ll need to add:

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

Keeping track of what we draw

To keep things simple for this example we will just make a rectangular object called Box. We’ll also make a method for creating Boxes a little easier.

// holds all our rectangles
var boxes = []; 

//Box object to hold data for all drawn rects
function Box() {
  this.x = 0;
  this.y = 0;
  this.w = 1; // default width and height?
  this.h = 1;
  this.fill = '#444444';
}

//Initialize a new Box, add it, and invalidate the canvas
function addRect(x, y, w, h, fill) {
  var rect = new Box;
  rect.x = x;
  rect.y = y;
  rect.w = w
  rect.h = h;
  rect.fill = fill;
  boxes.push(rect);
  invalidate();
}

Initialization

I’m going to add a bunch of variables for keeping track of the drawing and mouse state. I already added boxes[] to keep track of each object, but we’ll also need a var for the canvas, the canvas’ 2d context (where wall drawing is done), whether the mouse is dragging, width/height of the canvas, and so on. We’ll also want to make a second canvas, for selection purposes, but I’ll talk about that later.

var canvas;
var ctx;
var WIDTH;
var HEIGHT;
var INTERVAL = 20;  // how often, in milliseconds, we check to see if a redraw is needed

var isDrag = false;
var mx, my; // mouse coordinates

 // when set to true, the canvas will redraw everything
 // invalidate() just sets this to false right now
 // we want to call invalidate() whenever we make a change
var canvasValid = false;

// The node (if any) being selected.
// If in the future we want to select multiple objects, this will get turned into an array
var mySel; 

// The selection color and width. Right now we have a red selection with a small width
var mySelColor = '#CC0000';
var mySelWidth = 2;

// we use a fake canvas to draw individual shapes for selection testing
var ghostcanvas;
var gctx; // fake canvas context

// since we can drag from anywhere in a node
// instead of just its x/y corner, we need to save
// the offset of the mouse when we start dragging.
var offsetx, offsety;

// Padding and border style widths for mouse offsets
var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop;

// initialize our canvas, add a ghost canvas, set draw loop
// then add everything we want to intially exist on the canvas
function init() {
  canvas = document.getElementById('canvas');
  HEIGHT = canvas.height;
  WIDTH = canvas.width;
  ctx = canvas.getContext('2d');
  ghostcanvas = document.createElement('canvas');
  ghostcanvas.height = HEIGHT;
  ghostcanvas.width = WIDTH;
  gctx = ghostcanvas.getContext('2d');
  
  //fixes a problem where double clicking causes text to get selected on the canvas
  canvas.onselectstart = function () { return false; }
  
  // fixes mouse co-ordinate problems when there's a border or padding
  // see getMouse for more detail
  if (document.defaultView && document.defaultView.getComputedStyle) {
    stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10)      || 0;
    stylePaddingTop  = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10)       || 0;
    styleBorderLeft  = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10)  || 0;
    styleBorderTop   = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10)   || 0;
  }

  // make draw() fire every INTERVAL milliseconds.
  setInterval(draw, INTERVAL);
  
  // add our events. Up and down are for dragging,
  // double click is for making new boxes
  canvas.onmousedown = myDown;
  canvas.onmouseup = myUp;
  canvas.ondblclick = myDblClick;
  
  // add custom initialization here:
  
  // add an orange rectangle
  addRect(200, 200, 40, 40, '#FFC02B');
  
  // add a smaller blue rectangle
  addRect(25, 90, 25, 25, '#2BB8FF');
}

Drawing

Since our canvas is animated (boxes move over time), we have to set up a draw loop as I did in the init() function.

We have to draw at a frame rate, maybe every 20 milliseconds or so. However, redrawing doesn’t just mean drawing the shapes over and over; we also have to clear the canvas before every redraw. If we don’t clear it, dragging will look like the box is making a solid line because none of the old box-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, so we will consider the canvas to be either valid or invalid.

If everything just got drawn, the canvas is valid and there’s no need to draw again. However, if we do something like add a new Box or try to move a box by dragging it, the canvas will get invalidated and draw() will do a clear-redraw-validate.

This isn’t the only way to optimize drawing, after all clearing and redrawing the entire canvas when one little box moves is excessive, but canvas invalidation is the only optimization we’re going to use for now.

// While draw is called as often as the INTERVAL variable demands,
// It only ever does something if the canvas gets invalidated by our code
function draw() {
  if (canvasValid == false) {
    clear(ctx);
    
    // Add stuff you want drawn in the background all the time here
    
    // draw all boxes
    var l = boxes.length;
    for (var i = 0; i < l; i++) {
        drawshape(ctx, boxes[i], boxes[i].fill);
    }
    
    // draw selection
    // right now this is just a stroke along the edge of the selected box
    if (mySel != null) {
      ctx.strokeStyle = mySelColor;
      ctx.lineWidth = mySelWidth;
      ctx.strokeRect(mySel.x,mySel.y,mySel.w,mySel.h);
    }
    
    // Add stuff you want drawn on top all the time here
    
    
    canvasValid = true;
  }
}

As you can see, we go through all of boxes[] and draw each one, in order from first to last. This will give the nice appearance of later boxes looking as if they are on top of earlier boxes. After all the boxes are drawn, a selection handle (if there's a selection) gets drawn around the box that mySel 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 better ways though, like using multiple canvases, but we won't go over that here.

Mouse events

Now we have objects, initialization, and a loop that will constantly re-draw when needed. All thats left is to make the mouse do things upon pressing, releasing, and double clicking.

With our MouseDown event we need to see if there are any objects we could have clicked on. And we don't want just any object; selections make the most sense when we only grab the top-most object.

Now we could do something very easy and just check the bounds of each of our boxes - see if the mouse co-ordinates lie within the boxes width and height range - but that isn't as extendable as I'd like. After all, What if later we want to select lines instead of boxes? Or select triangles? Or select text?

So we're going to do selection in a more general way: We will draw each shape, one at a time, onto a "ghost" canvas, and see if the mouse co-ordinates lie on a drawn pixel or not.

A ghost canvas (or fake canvas, or temporary canvas) is a second canvas that we created in the same size and shape as our normal one. Only nothing from it will ever get seen, because we only created it in code and never added it to the page. Go back and look at ghostcanvas and its context (gctx) in the init() function to see how it was made.

// Happens when the mouse is clicked in the canvas
function myDown(e){
  getMouse(e);
  clear(gctx); // clear the ghost canvas from its last use

  // run through all the boxes
  var l = boxes.length;
  for (var i = l-1; i >= 0; i--) {
    // draw shape onto ghost context
    drawshape(gctx, boxes[i], 'black');
    
    // get image data at the mouse x,y pixel
    var imageData = gctx.getImageData(mx, my, 1, 1);
    var index = (mx + my * imageData.width) * 4;
    
    // if the mouse pixel exists, select and break
    if (imageData.data[3] > 0) {
      mySel = boxes[i];
      offsetx = mx - mySel.x;
      offsety = my - mySel.y;
      mySel.x = mx - offsetx;
      mySel.y = my - offsety;
      isDrag = true;
      canvas.onmousemove = myMove;
      invalidate();
      clear(gctx);
      return;
    }
    
  }
  // havent returned means we have selected nothing
  mySel = null;
  // clear the ghost canvas for next time
  clear(gctx);
  // invalidate because we might need the selection border to disappear
  invalidate();
}

myMove and myUp are pretty self explanatory. the var isDrag becomes true if myDown found something to select, and it becomes false again when the mouse is released (myUp).

// Happens when the mouse is moving inside the canvas
function myMove(e){
  if (isDrag){
    getMouse(e);
    
    mySel.x = mx - offsetx;
    mySel.y = my - offsety;   
    
    // something is changing position so we better invalidate the canvas!
    invalidate();
  }
}

function myUp(){
  isDrag = false;
  canvas.onmousemove = null;
}

There are a few little methods I added that are not shown, such as one to correctly get the mouse position in a canvas. 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 how in the comments.

Part 2 of this tutorial is about resizing the shapes and can be found here.

How to play Age of Empires II on Windows Vista and Windows 7

I love Age of Empires II. I love all real-time strategy games, but Age of Empires II must be among the finest I’ve ever played, especially as a multiplayer game.

Unfortunately, getting Age of Empires to work in this modern day is a bit of a pain. The game was built on network technology known as IPX that has since gone the way of the dinosaurs. So far gone, in fact, that Microsoft decided not to include it in Vista and Windows 7. All of my computers are using Windows 7 now, so getting the game to play over LAN proved to be difficult.

I didn’t want to deal with trying to hodge-podge together an IPX installation, so I decided to look for ways for the TCP/IP method of gameplay to work. This method rarely worked for me, and when it did it only worked on some computers and not others.

Apparently, all I needed to do was assign all the computers that were playing in the game to have static IP addresses. If you don’t know what that is, there’s a link to a guide at the bottom of this article. Set static IPs on every computer that will be playing, not just the host.

Then, on the computer hosting, select Internet TCP/IP Connection for DirectPlay and NOT the LAN option. For some reason, selecting the LAN option caused issues. However, all the computers that will be joining can just select the LAN option.

Assuming there are no firewall issues, you should be good to go. I tested this with Windows 7 only machines, and only over LAN. If anyone has tried this as described and couldn’t get it to work, I’d like to hear from you.

Have fun playing!

Here’s a wonderful guide from PortForward.com on setting up a static IP.