One of the things that I like about Canvas is that it provides a really nice low-level API, allowing for a great degree of control over the drawing. The problem is that, without using an external library, some simple tasks are a little bit cumbersome and hard to maintain.
For example, let's assume we want to create a simple page like:
- Two boxes, one red and one blue.
- Each box will show an alert when clicked upon.
The code should be something like this:
<html> <head> <script type="text/javascript" src="jquery-1.7.1.min.js"></script> <script type="text/javascript"> $(function () { var canvas = $('#canvas')[0]; var context = canvas.getContext('2d'); if (context) { context.fillStyle = 'red'; context.fillRect(0, 0, 100, 100); context.fillStyle = 'blue'; context.fillRect(0, 100, 100, 100); } $('#canvas').click(function (e) { if (e.clientX >= 0 && e.clientX < 100) { if (e.clientY >= 0 && e.clientY <= 100) { alert('red square clicked'); } if (e.clientY >= 100 && e.clientY <= 200) { alert('blue square clicked'); } } }); }); </script> </head> <body> <canvas id='canvas' width='400' height='400'></canvas> </body> </html>Having one click event-handler and comparing manually the coordinates of objects inside the canvas is a little bit old-school. Nowadays, and with the likes of jQuery, one gets spoiled by it's declarative syntax. For example, with jQuery the event handlers are created like (assuming elements 'red' and 'blue'):
$('#blue').click(function() { alert('blue square clicked'); }); $('#red').click(function() { alert('red square clicked'); });Wouldn't it be great to mix the canvas API with a declarative syntax like jQuery? Fortunately there's a library which does just that. It's called KineticJS.
KineticJS API is, IMHO, brilliant. It mixes a declarative syntax with full control over the Canvas Context element. For example, drawing a simple square:
var redsquare = new Kinetic.Shape(function () { var context = this.getContext(); context.fillStyle = 'red'; context.fillRect(0, 0, 100, 100); });The canvas code is exactly the same. The difference is that we're creating the drawing in the context (pun intended) of a Kinetic.Shape object. Thus, the rectangle becomes a first class citizen, providing properties, methods and events. For example, the click event is implemented as:
redsquare.on("click", function () { alert('red square clicked'); });Hell yeah, and although the API is very simple this is just the tip of the Iceberg. Scaling, rotating, drag-and-drop, etc, you name it. See the full documentation here.
For me writing Canvas code without KineticJS is like writing Javascript without jQuery: it's certainly possible, but why should we? :P
The full source-code with KineticJS:
<html> <head> <script type="text/javascript" src="jquery-1.7.1.min.js"></script> <script type="text/javascript" src="kinectic-v.3.7.2.min.js"></script> <script type="text/javascript"> $(function () { var stage = new Kinetic.Stage("canvas", 400, 400); var layer = new Kinetic.Layer(); var redsquare = new Kinetic.Shape(function () { var context = this.getContext(); context.fillStyle = 'red'; context.fillRect(0, 0, 100, 100); }); var bluesquare = new Kinetic.Shape(function () { var context = this.getContext(); context.fillStyle = 'blue'; context.fillRect(0, 100, 100, 100); }); redsquare.on("click", function () { alert('red square clicked'); }); bluesquare.on("click", function () { alert('blue square clicked'); }); layer.add(redsquare); layer.add(bluesquare); stage.add(layer); }); </script> </head> <body> <div id='canvas'></div> </body> </html>
No comments:
Post a Comment