oCanvas makes me wonder when it’s right to use libraries

March 28th, 2011

In case you haven’t heard of it yet, oCanvas is a library that enables you to write object based code when writing for HTML5’s canvas element. It makes creating and interacting with elements on the canvas faster and easier than writing pure JavaScript. Creating something like a rectangle and enabling the user to drag it around the canvas only takes eight lines of code, which I think for a beginner is great for someone that’s not that comfortable working with the canvas tag yet.

Here’s a quick example that creates a rectangle and makes it draggable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script src="http://ajax.cdnjs.com/ajax/libs/ocanvas/1.0/ocanvas.min.js"></script>
<script>
var canvas = oCanvas.create({
  canvas: '#canvas'
});
var rect = canvas.display.rectangle({
  x: canvas.width / 2 - 50,
  y: canvas.height /2 - 25,
  width: 100,
  height: 50,
  fill: '#000’'
});
canvas.addChild(rect);
rect.dragAndDrop();
</script>

First, we have to link to the oCanvas library file and then we create a variable called canvas that references our canvas element on the document. Next we create a rectangle and give it’s positioning, width, height and fill color. This is pretty close to creating a JavaScript object, so if you have some experience with JS already, this should pretty easy to pick up. Next we add it to the canvas and then enable drag and drop by using the built in dragAndDrop function. With just that code, we’ve create a rectangle that we can drag around the canvas.

oCanvas isn’t as robust as something like EaselJS or Impact, but I think it’s great for beginners. I do have one concern about it, you still have to download a library file to make it work and I’m slowly becoming of the opinion, if you don’t need to use a library file, you probably shouldn’t. And, if even though the site says the production version is 15Kb, Chrome’s developer tools say it’s 55Kb and when I downloaded it, it was the same size on my computer. That’s twice the size of jQuery and depending on the site and connection, that could slow down a website a fair amount.

So, just as a test, I thought I’d compare that to the same effect built with just regular JavaScript. Here’s what I wrote:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
var canvas, ctx, width, height, mouseX, mouseY, rectangle, drag = false;

function init() {
  canvas = document.getElementById('canvas');
  ctx = canvas.getContext('2d');
  width = canvas.width;
  height = canvas.height;
  rectangle = {
    x: width / 2 - 50,
    y: height / 2 - 25,
    w: 100,
    h: 50
  }
  drawCanvas();
  canvas.addEventListener('mousedown', mouseDown, false);
  canvas.addEventListener('mouseup', mouseUp, false);
  canvas.addEventListener('mousemove', mouseMove, false);
}

function mouseDown(e) {
  var x = e.pageX - this.offsetLeft,
      y = e.pageY - this.offsetTop;
  if (x > rectangle.x && x < rectangle.x + rectangle.w && y > rectangle.y && y < rectangle.y + rectangle.h) {
    drag = true;
    mouseX = x - rectangle.x;
    mouseY = y - rectangle.y;
  } else {
    drag = false;
  }
}

function mouseUp() {
  drag = false;
}

function mouseMove(e) {
  if (drag) {
    rectangle.x = e.pageX - this.offsetLeft - mouseX;
    rectangle.y = e.pageY - this.offsetTop - mouseY;
    drawCanvas();
  }
}

function drawCanvas() {
  ctx.clearRect(0,0,width,height);
  ctx.fillRect(rectangle.x, rectangle.y, rectangle.w, rectangle.h);
}
init();

OK, that’s about 4 times the amount of code that we have to write, but a lot less code that the browser has to run in order for us to have the same effect. I’m not going to go through this line by line, most of the code is explained in my earlier posts on canvas and JS. All you really need to know, is that we’re checking to see if the mouse cursor is in the rectangle when the mouse is clicked and if it is, we’ll set the drag variable to true. Next, if drag is true and the most is then moved, the square is repositioned to match that new position using the mouseMove function.

But how it works isn’t really what I was going after here, it’s how much less the file size is, this version is only 1.4Kb. That’s a pretty big difference for the same effect. And this took me a bit longer to write but now that I have, it’s there for me to reuse and modify whenever I need this again.

I’m not writing this to rip on oCanvas, in fact, I’d say I’m a fan of it. But I think this is a great way for people to get started with the canvas tag and I think in most instances, that extra 55Kb wouldn’t be that big of a deal. I just think developers need to think of things like this as a way to get into working with new web technologies, not as something they should always rely on.

One Response to oCanvas makes me wonder when it’s right to use libraries

  1. Happy to find posts discussing my library! :)

    You are right. For some things, this library really is not the best choice. But I also think you miss some of the points of the library. It abstracts away things the user don’t want to think about. What if you would rotate the rectangle and want to move it while it is rotating? First you would have to work with the unfriendly transformation matrix. Then you would need to check if the mouse pointer is inside the object for that rotation. That can be kind of tricky for some objects, and might not be something a user would want to deal with.

    The filesize is also a little misleading. It says it’s 15 kB minified and gzipped. Gzipping happens on the server side when you serve it to the client. If you would download the file to desktop it will not be gzipped, because the browser has already unpacked it. If you look at jQuery that you mention, it says 29 kB minified and gzipped, but when downloading it to desktop, it is actually 83 kB. The file hosted on ocanvas.org is also not gzipped, since my host doesn’t support gzip (maybe I will switch host someday), which is why Chrome reported 55 kB for the file.

Leave a Reply

Your email address will not be published. Required fields are marked *