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