Recursively Drawing Trees with JavaScript and Canvas

November 22, 2009

I have written an article titled Graphics Programming with Canvas for the upcoming December 2009 edition of JSMag. One of the examples I came up with for the article was a recursive tree drawing algorithm. I had quite a bit of fun tweaking different values and seeing what sort of tree would be produced. After a while it got a bit boring changing a value, saving the JavaScript and then refreshing the page, so with the help of jQuery UI I came up with an interactive version. Below are a couple of tree images I’ve generated with the tool:

tree

tree


You can view the page source to see what’s going on behind the scenes, but for full details check out the December edition of JSMag. Give it a try for yourself, generate your own tree!

Debugging Javascript in Internet Explorer 6

May 16, 2009

If you’ve ever got to work with javascript and IE6 then you might want to read the guest post I wrote for Six Revisions: Debugging Javascript in Internet Explorer 6.

The post describes how to configure IE6 so that instead of displaying subtle and cryptic error messages when you run into a Javascript issue it will instead allow you to debug the problem with the help of Visual Studio’s powerful debugger. I’ve put together a small slideshow that includes a summary of the content:

Javascript, JSON and PHP

March 29, 2009

JSON data is commonly used as a simple way to send data back to client side javascript from the server. For example, a PHP script may output the following JSON to confirm that an action was taken:

{success: true, message: "It worked!"}

or in the case of failure:

{success: fase, message: "It didn't work!"}

Below is a basic javascript callback function to process the JSON data, displaying the returned message:

function callback(data) {
    if(data.success) alert(data.message);
    else alert('ERROR:' + data.message);
}

Sometimes it’s actually useful to send back javascript code to in the JSON data, to be run on the client. For example, if an Ajax request is made that updates some account information we could return javascript code to update several parts of the page with the new information. Here’s PHP code that outputs JSON data which includes javascript code:

$response = array('success' => 'true',
    'code' => "jQuery('#id').html('Success!');");
echo json_encode($response);
// Outputs {success: true, code: "jQuery('#id').html('Success!');"}

Note how in the returned JSON data “code” is actually a string, so it won’t be possible to run the code simply by doing “data.code()” on the client. Instead we must explicitly tell javascript to evaluate the string as code. Below is an example of how we can do this using eval:

function callback(data) {
    if(data.success && data.code) eval(data.code);
}

If we wanted to update the page with HTML more complicate the the simple “Success!” message in the previous example we must be careful to escape any quotes in the HTML correctly. If we wanted to set the content to: “Javascript”, “json”, “PHP” then we’d need to do the following:

$response = array('success' => 'true',
    'code' => "jQuery('#id').html('\"Javascript\", \"json\", \"PHP"');");
echo json_encode($response);

And It’s easy to imagine a far more complicated example. The code becomes less readable, and if you accidentally forget to escape one of the quotes, or escape of the quotes that shouldn’t be escaped, then the whole thing breaks. A nice alternative is ty store the HTML as a separate JSON property and then to reference it, avoiding the need to escape the quotes and making the code easier to read:

$response = array('success' => 'true',
    'html' => '"Javascript", "json", "PHP"',
    'code' => "jQuery('#id').html(this.html);");
echo json_encode($response);

However, to make the “this.html” reference work the clients side callback function will need to changed, as eval() runs the code in global scope. This means that “this.html” will refer to a global html variable rather than the one in our JSON data. We can get around this problem by using the apply function as follows:

function callback(data) {
    if(data.success && data.code) {
        var f = new Function(data.code);
        f.apply(data);
    }
}

And here’s a complete example which uses jQuery to perform the Ajax call:

jQuery.get('update.php', {} function(data) {
    if(data.success && data.code) {
        var f = new Function(data.code);
        f.apply(data);
    }, 'json');

jQuery Draggable Implementation

February 16, 2009

jQuery UI is an excellent add-on library for jQuery that provides all sorts of UI widgets, effects and behaviours. One particularly useful function is provides is to make any element on the page draggable, so that it can be moved about with the mouse.

Because of all the features that jQuery UI provides the library is fairly large, about 450KB uncompressed. It is possible to only include specific parts of the library, but even the bare minimum required for the draggables feature weighs in at just over 40KB uncompressed.

Therefore I decided to write my own lightweight draggable implementation using only jQuery. The code is shown below:

// Make an element draggable using jQuery
var makeDraggable = function(element) {
	element = jQuery(element);

	// Move the element by the amount of change in the mouse position
	var move = function(event) {
		if(element.data('mouseMove')) {
			var changeX = event.clientX - element.data('mouseX');
			var changeY = event.clientY - element.data('mouseY');

			var newX = parseInt(element.css('left')) + changeX;
			var newY = parseInt(element.css('top')) + changeY;

			element.css('left', newX);
			element.css('top', newY);

			element.data('mouseX', event.clientX);
			element.data('mouseY', event.clientY);
		}
	}

	element.mousedown(function(event) {
		element.data('mouseMove', true);
		element.data('mouseX', event.clientX);
		element.data('mouseY', event.clientY);
	});

	element.parents(':last').mouseup(function() {
		element.data('mouseMove', false);
	});

	element.mouseout(move);
	element.mousemove(move);
}

The element you pass to makeDraggable should already have absolute or fixed CSS positioning, and a top and left CSS value set. Something like the following:

<div id='draggable' style='position: absolute; top: 100; left: 200; padding: 50px; background: black; border: 2px solid #aaa;'>
This box is draggable!
</div>
<script type="text/javascript">
makeDraggable(jQuery('#draggable'));
</script>

Then just click on the div and move the mouse to drag it around.

Obviously it isn’t as flexible as the jQuery UI version, but it is a useful alternative if you want to save on the amount of data your user’s will need to download and you don’t require any other jQuery UI features.

Ubiquity CmdUtils.injectHTML workaround

January 29, 2009

If you haven’t already heard about Mozilla Ubiquity I suggest you watch the introductory video, which will explain it far better than I can.

I’ve been having a bit of a play around with it, and written a few small commands. The API documentation is really good, but this being early alpha software (currently v0.1.5) not everything works as expected.

For one of my commands I wanted to inject some HTML into the current webpage. Looking through the docs CmdUtils.injectHTML seemed to be exactly what I was after. Unfortunately it doesn’t work, but the workaround is simple enough:

var html = 'content to inject';
var doc = CmdUtils.getDocument();
doc.body.innerHTML += html;

Hopefully this will be fixed in the next release.

Older Posts »