matthew ephraim

Archive for the ‘javascript’ Category

Introducing Candid Canvas

Wednesday, July 21st, 2010

The Canvas Tag

If you’re a web developer (or even mildly interested in the world of web development) you’ve probably heard of HTML5’s new Canvas tag. You’re probably also aware that the Canvas tag allows web developers to create some really great animations right in the browser. No plugins needed (well, depending on your browser, maybe one plugin).

As soon as I saw what was possible with the Canvas tag, I wanted to start using it myself. So, I looked at some of the Canvas tutorials available online and figured out how to create some simple drawings. It was fun, and simple, and I was happy.

And then I decided to try my hand at creating some Canvas animations.

The Problem

Now, I’m not a Canvas expert, so my analysis could be way off base, but I quickly came to the conclusion that creating a Canvas animation could be quite difficult. It’s fairly easy to do if your animation only has a few elements. And it’s manageable if you don’t mind having a lot of extra code for handling the animation’s timing and state variables. But, as time went on, I found that even simple animations became difficult to manage very quickly. My hat’s off to the developers that have created some of the more complex Canvas animations out there. I don’t know how you do it.

My first instinct when I began to run into problems with the Canvas animations I was trying to create was to look for a Canvas animation library that might help me out. It turns out that there are a few out there. Unfortunately, I didn’t find one that I felt fit well with the kinds of animations I wanted to create.

And so, with a stack of problems I intended to solve, I set out to create a Canvas animation library that would solve each and every one of them.

Candid Canvas

What I came up with was a new Canvas animation library that I call Candid Canvas.

  • Unlike several of the other Canvas animation libraries out there, Candid Canvas doesn’t provide you with any special drawing tools. You’re still on your own when it comes to drawing your animation.
  • Candid Canvas also doesn’t keep track of the elements that have been drawn to the Canvas tag. You’re on your own for that too.
  • Candid Canvas is intended to help you manage the parts of creating a Canvas animation related to, well…animating it.
  • Candid Canvas helps you break down your animation into separate scenes.
  • And it helps you break your scenes down into individual elements responsible for drawing different pieces of the scene.
  • Candid Canvas also helps you play, pause and reset your animation.

Candid Canvas is not a library for everyone. But if you’re looking for a little extra help when creating Canvas animation, I hope that Candid Canvas will work for you!

Download, contribute and submit bugs and feature requests at the Candid Canvas Github project.

Draggability for the Raphaël Library

Saturday, October 31st, 2009

I’ve been using the Raphaël JavaScript library a lot lately for a JavaScript SVG project I’ve been working on. It’s easy to use and eases a lot of the pain of using JavaScript with SVG. However, I eventually came to a point where I needed to have SVG elements that could be dragged around on the Raphael canvas. After looking around for a good plugin that would allow me to do what I wanted, I decided that I needed to write my own. The result is the raphael.draggable plugin.

raphael.draggable is fairly straightforward to use. You simply need to call the draggable.enable() on the raphael object you would like to enable the plugin for. raphael.draggable works for all raphael elements and for raphael sets as well. Sets that have raphael.draggable enabled will drag all elements in the set whenever any element in the set is dragged.

Using the raphael.draggable plugin

 // Creating a canvas and enabling draggable for it
var paper = Raphael(0,0, 800, 600);
paper.draggable.enable();

// Creating a rectangle element and enabling draggable for it
var rect = paper.rect(0, 0, 100, 100);
rect.attr({ 'fill': 'white' });
rect.draggable.enable();

// Creating a set and enabling draggable for it
var set = paper.set();
set.draggable.enable();
set.push(rect);

Currently, raphael.draggable has only been tested for Firefox and Safari. Those are the only two browsers I needed to test it for. Source code and documentation are available on github. Constructive criticism, and especially constructive contributions to the code are welcome!

Screwing Around With Screw.Unit

Wednesday, November 26th, 2008

I just started using the delightfully named Screw.Unit for JavaScript testing, and I have to say that, so far, I’m pretty pleased with it. Screw.Unit is a JavaScript testing framework that allows you to easily create and run unit tests for your JavaScript code. For example, here is a really simple hello world type test written with Screw.Unit:

JavaScript/Screw.Unit
describe("A simple hello world test", function()
{
    it("is a test for truth example", function()
    {
        expect(true).to(equal, true);
    };
};

If I were to run the test on a page that had the framework loaded in, I’d get a nice pretty rundown of my tests, showing that the hello world test had indeed passed (true does, in fact, equal true).

One thing that I immediately wondered about was how the keywords in the framework worked. At first, I assumed they were global variables and was a little put off by that idea. Would functionality like “describe”, “expect” and “it” interfere with other code that happened to use those same function names or variables? Fortunately, I was surprised to find this code in the framework:

JavaScript/Screw.Unit
var contents = fn.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1];
var fn = new Function("matchers", "specifications",
  "with (specifications) { with (matchers) { " + contents + " } }"
);

fn.call(this, Screw.Matchers, Screw.Specifications);

Located in the initialization portion of Screw.Unit, this cryptic looking piece of code is actually doing something very clever. It’s using the Function.toString() method to extract the content of the function wrapper around all of your tests. It’s then taking the contents of that function and creating a new function that is using the “with” keyword to execute your code in the context of the framework’s keywords and functions.

In other words, it’s taking your tests and tricking JavaScript into thinking that your test functions have access to the properties and methods stored in Screw.Matchers and Screw.Specifications. This gives you access to the framework functionality without leaking any variables into the global namespace.

That sort of cleverness gives me hope that JavaScript has a bright future ahead.

It’s a (Firefox) bug!

Tuesday, September 30th, 2008

Sometimes it’s a relief when you find that a bug you’re trying to fix in your own code is actually related to someone else’s code. I’ve been trying to figure out why large text blocks inside of an xml file keep getting truncated when I read the file in with JavaScript. Turns out it’s Firefox Bug 452675.

Bug
FF 3 creates multiple #text nodes for elements with well under 
4096 characters of text data

Good to know I’m not crazy…

Keep tinyMCEPopup From Loading the Popup CSS File

Saturday, July 12th, 2008

This week I have been developing my first TinyMCE plugin. One of the first steps was designing the popup dialog box that would be associated with the plugin. Initially, everything was going smoothly. I had the XHTML and CSS just the way I wanted it and I was ready to move on to the next step of developing the JavaScript that would power the functionality of the plugin.

One of the utility files that TinyMCE allows you to include is a file called tiny_mce_popup.js. Including this file gives you access to a class called tinyMCEPopup. This class provides you with some helper functions that come in handy when developing the dialog box for a TinyMCE plugin. Unfortunately, including the helper file also has a side effect: the helper class will automatically include the current theme’s css file. In the case of my plugin, the css file for the current theme completely changed the way my plugin’s XHTML was styled. And not in a good way.

One solution would have been to modify my stylesheet or alter my XHTML so that the stylesheet didn’t interfere with the way I wanted the page to look. I tried to do this initially, but what I really wanted was for the theme stylesheet not to be included at all. As far as I can tell there’s no built in way to do force the tinyMCEPopup class to not include the stylesheet. So, I developed a workaround that seems to keep the stylesheet from loading without causing any side effects.

The first thing I needed to do was to unset the property that defined the theme stylesheet for popup dialogs. That way when the tinyMCEPopup class tried to include the file, it wouldn’t find anything to include. The location of the popup stylesheet is stored in the settings for the editor instance under editor.settings.popup_css. I figured out that the property could be unset at the beginning of the command that was executed when the button for my plugin was clicked.

JavaScript
editor.addCommand('mceMyPluginCommand', function() 
{		
	// Set the popup css to null while page loads 
	// because my plugin uses its own css
	editor.settings.popup_css = null; 
	...
});

This worked fine, but setting the popup_css property to null caused the stylesheet for any other plugin’s popup dialog to not load correctly. To get around this problem I needed to restore the original popup_css property once my plugin’s dialog box was finished loading. To do this, I simply added a command to the editor that would restore the original popup_css property.

JavaScript
// Registers an event that will 
// Add command to restore the original css file
ed.onInit.add(function() 
{ 
	var origCss = editor.settings.popup_css;
	editor.addCommand("mceMyPlugin_restoreCss", 
                       function() { editor.settings.popup_css = origCss; });
});

The previous two pieces of code could be run during the initialization of my plugin. Finally, I needed to use the tinyMCEPopup class inside of my popup dialog to call the function that restored the css.

JavaScript
// Restore the popup css to the original theme css
tinyMCEPopup.execCommand("mceMyPlugin_restoreCss");

It’s not the most elegant solution to the problem, but so far it’s the only way I’ve been able to figure out how to force the tinyMCEPopup class not to load the theme css file.

Be wary of JavaScript reserved words and globals

Monday, October 29th, 2007

If you’re writing some JavaScript and suddenly it stops working without any warnings or errors, make sure you’re not stepping on any reserved words or global objects. Tonight, I had a script that was working perfectly in Firefox, but as soon as I tested it in Safari it completely failed. It took me a little while to realize that I had named a property on an object “default”. Stupid mistake, but Firefox didn’t warn me about it and instead happily ran the script. I guess it goes to show that even standards compliant browsers don’t always behave the way you expect them to.

The Core JavaScript Reference is a good place to start if you’re looking for a list of keywords. Particularly the sections on Global Objects and Reserved Words. This list also wrapped many of them up nicely.

JavaScript Mouse Tracker

Saturday, October 20th, 2007

A while ago, I was thinking about software programs like Camtasia that allow you capture a user’s activity as they work on a computer. Screen capturing programs are useful for usability studies because they allow you play back a user’s activity later on when you are evaluating their performance on a set of tasks. I started to wonder if their were any options for capturing a user’s activity remotely through the browser. When I didn’t find anything I thought was compelling, I decided to try writing my own.

What I came up with was a JavaScript class I called MouseMovie that could be used to record the mouse movements a user made while on a page. The first draft is pretty rough, but it will allow you to create a new mouse tracker, start tracking the mouse movements a user makes on a page and then stop the tracker. Once data has been captured by the tacker, you can use the mouse timeline to replay the user’s movements or trace the path of the user’s movements.

JavaScript
/* Create a new tracker, 
start it and stop it and then use 
the timeline to animate 
and trace the mouse path. */
var MyTracker = new MouseMovie.Tracker(); 
MyTracker.start(); 
MyTracker.stop(); 
MouseMovie.Animate({TimeLine : MyTracker.TimeLine});
MouseMovie.Trace(MyTracker.TimeLine);

Currently, there is no way to persist the user’s movements to a file or database, but I’d like to make it possible to store the movements and play them back at another time. A simple demo of the mouse tracker can be found here