GBCanvas: A canvas experiment

I’m pretty sure my body doesn’t work on a 24 hour day cycle. I went to bed around 2300 two nights ago, and got up around seven. Though I’d been lying in bed awake, trying to sleep for much longer. I say I got about five or six hours sleep that night. I went to bed at ten tonight, and was awake by two. I feel I could stay awake until tonight now. I’m not tired or anything. Maybe so little sleep has just become a habit.

My sleep schedule isn’t why I’m here.

I’m doing some tests with the canvas element, and decided to make a class for it. You can see it over at the GBCanvas github I set up for it. (I’ve never used github. Just heard a lot about it.) The code is kinda broken at the moment though.

The class is based on the idea of pseudo-pixels, where you have a 300×300 canvas, and can set it to have ten rows and twelve columns. Then you can manipulate each of those segments, which I’ve decided to call pixels. The “GB” comes from Gameboy, because I figured it’d be cool to remake Zelda with canvas.

I want to add an edit mode so the user could do something like

$(document).ready (function () {
  var canvas = new gbCanvas ('canvasid1');
  canvas.editModeOn (true);
});

Which would allow clicking of a pixel and it fills it with a chosen colour. I  mostly want this feature so I can create pixel art, and then get the raw data:image/png data, which I can import into the project whenever. I’m aware I could just create sprites in Paint or something and import the file, but I don’t want to. I’m fond of imposing restrictions stubbornly unto myself.

After a few rethinks, I figured it would be fair simple to just bind a click event to the canvas

//  Turns on edit mode so onclicks are registered and bubbled
this.editModeOn = function (mode) {
  if (mode) {
    //  .click is a jquery thing
    this.canvasDiv.click (this.editModeClick);
  }
}

And then working out which pixel was clicked, and filling it with colour

  this.editModeClick = function (event) {
  //  getSelectPoint just returns an array with the X and Y coord of the click
  //  relative to the top left of the image (to avoid problems with scrolling)
  clickPoints = getSelectionPoint (event, this.canvasID);
  console.log (clickPoints);
  //  Work out which "pixel" they just clicked
  var coordWidth = parseInt (clickPoints[0] / pixelWidth);
  var coordLength = parseInt (clickPoints[1] / pixelHeight);
  console.log (coordWidth + ', ' + coordLength);
  this.colourPixel (coordWidth, corrdLength);
}

This doesn’t seem to work because the event is rarely passed. It is sometimes, but hardly ever. The function is bound correctly. It’s entirely a problem with the event being passed – something I’ve always had trouble with if I’m honest…

Update: Ladies and gents, do yourself a favour and check all your variables before you go bitching on your blog about your code not working. The event was being passed fine. The problem with my code is that since it’s a function that’s being bound to an event, it effectively loses it’s place in the instance of the class, so it no longer has access to the this variable.

My problem was that this.cavasID was undefined.

So, I fix that by simply passing it “this”. Changing the bound event function to something like this:

this.editModeClick = function (event, _this) {
  console.log (event);
  console.log (_this);
  clickPoints = getSelectionPoint (event, _this.canvasID);
  console.log (clickPoints);
  //  Work out which "pixel" they just clicked
  var coordWidth = parseInt (clickPoints[0] / _this.pixelWidth);
  var coordLength = parseInt (clickPoints[1] / _this.pixelHeight);
  console.log (coordWidth + ', ' + coordLength);
  _this.colourPixel (coordWidth, corrdLength);
}

That’s all well and good, but now I’m confused as to how to bind it…

this.canvasDiv.click (this.editModeClick (event, this));

The event needs to be the first argument, but I’ve no idea how to pass the event here… That obviously doesn’t work (event is undeclared).

Edit: Of course it was something ridiculously simple.

var self = this;
this.canvasDiv.click (function (event) { self.editModeClick (event, self) } );

Comments are closed.