JavaScript Canvas.DrawWindow implementation

I have implemented DrawWindow (HTML rendering) functionality in Canvas. It is essentially rendering HTML inside of the canvas tag without modifying the original DOM. This took a lot of trial and error, but it is working pretty well now. The code is online here: https://github.com/bgrins/DrawWindow, and a really minimal project page is here: DrawWindow demo.

I recently found a very good implementation of this same functionality, called html2canvas, that was just released. That implementation includes nice demos and a test console, so it is worth checking out. That version is quite a bit more polished, so when I work on mine more, I will have to check out some of the great work here: https://github.com/niklasvh/html2canvas.

This functionality is necessary for web design type applications that require a colorpicker based on the current DOM, or for feedback type applications that require sending screenshots. Great to see this being built out!

bindWithDelay jQuery Plugin - Now With Throttling

I decided to add in throttling functionality to the jquery bindWithDelay plugin. This is a nice feature that didn't require very many changes to the code (see the: diff).

What is throttling?

Imagine you are scrolling down a long page for 3 seconds and you have bindWithDelay running with a timeout of 1000ms. By default, your event will only fire a second after you have completely finished scrolling. If you have the optional throttling on, it will fire once per second during the scrolling - a total of 3 times instead of 1.

Checkout the throttling demo to see what it is doing.

wordsolver.js

I was playing around with unscrambling words recently, and decided to implement a solver in JavaScript. I called it wordsolver.js.

Demo

There is a wordsolver demo on my site. Try typing in URESMTA or something to see all the words that get unscrambled.

Code

All code can be found in the wordsolver repository on github. In particular, here is the file that does all the heavy lifting. It is all available under the MIT license.

How does it perform?

Smoother than I expected it to. The load time for the dictionaries can be pretty slow (they are anywhere from 1.7MB to 2.6MB depending on the dictionary), but once it loads, it finds words pretty fast and tries to cache results. Warning: it will probably crash an iPhone while trying to load the dictionary array into memory

Safer JSONP

I read a nice write up on on JSON and JSONP by Angus Croll. He provided a sample implementation of a safe JSONP library.

The library is concise and does the trick for a single connection, but I found it didn't handle multiple connections. It would overwrite a single global callback, so if you had connections of varying speeds, you would undoubtedly get errors. For instance, "Request 1" is very slow, and "Request 2" gets finished before it. When "Request 1" gets finished, it uses the callback for "Request 2". This actually happened the first time I loaded it up and ran it. Not good.

Here is a simple updated version that takes care of that particular problem.

/*
An implementation of: http://javascriptweblog.wordpress.com/2010/11/29/json-and-jsonp/
that handles multiple connections at once (don't want to replace the
global callback if second request is sent after the first, but returns before).
*/

(function(global) {

var evalJSONP = function(callback) {
  return function(data) {
    var validJSON = false;
    if (typeof data == "string") {
      try {validJSON = JSON.parse(data);} catch (e) {
        /*invalid JSON*/}
    } else {
      validJSON = JSON.parse(JSON.stringify(data));
      window.console && console.warn(
        'response data was not a JSON string');
    }
    if (validJSON) {
      callback(validJSON);
    } else {
      throw("JSONP call returned invalid or empty JSON");
    }
  }
};

var callbackCounter = ;
global.saferJSONP = function(url, callback) {
  var fn = 'JSONPCallback_' + callbackCounter++;
  global[fn] = evalJSONP(callback);
  url = url.replace('=JSONPCallback', '=' + fn);

  var scriptTag = document.createElement('SCRIPT');
  scriptTag.src = url;
  document.getElementsByTagName('HEAD')[].appendChild(scriptTag);
};

})(this);

To test it out:

var obamaTweets = "http://www.twitter.com/status/user_timeline/BARACKOBAMA.json?count=5&callback=JSONPCallback";
saferJSONP(obamaTweets, function(data) {console.log(data[].text)});

var reddits = "http://www.reddit.com/.json?limit=1&jsonp=JSONPCallback";
saferJSONP(reddits , function(data) {console.log(data.data.children[].data.title)});

If you are really worried about multiple global objects JSONPCallback_1, JSONPCallback_2, etc - you could store them all in an array instead. Like this:

(function(global) {

var evalJSONP = function(callback) {
  return function(data) {
    var validJSON = false;
    if (typeof data == "string") {
      try {validJSON = JSON.parse(data);} catch (e) {
        /*invalid JSON*/}
    } else {
      validJSON = JSON.parse(JSON.stringify(data));
      window.console && console.warn(
        'response data was not a JSON string');
    }
    if (validJSON) {
      callback(validJSON);
    } else {
      throw("JSONP call returned invalid or empty JSON");
    }
  }
};

var callbackCounter = ;
global.JSONPCallbacks = [];
global.saferJSONP = function(url, callback) {
  var count = callbackCounter++;
  global.JSONPCallbacks[count] = evalJSONP(callback);
  url = url.replace('=JSONPCallback', '=JSONPCallbacks[' + count + ']');

  var scriptTag = document.createElement('SCRIPT');
  scriptTag.src = url;
  document.getElementsByTagName('HEAD')[].appendChild(scriptTag);
};

})(this);

filereader.js - A Lightweight FileReader Wrapper

I am working on project that needs to read local files. This relies on the FileReader interface, and I couldn't find any JavaScript libraries to help out with common usage for this, so I made one.

View the project page and demo for the FileReader.js JavaScript FileReader Plugin!

FileReader is a JavaScript interface that allows you to read local files as binary. This is available in supported browsers when a user drags and drops files into a browser window or selects files from an input with a type of file. See the FileReader specification for more information.

filereader.js is a wrapper for accessing this functionality. It can be called using:

FileReaderJS.setupInput(fileInput, opts);
FileReaderJS.setupDrop(dropbox, opts);

If you use jQuery, you can access these calls with:

$("#fileInput").fileReaderJS(opts);
$("#dropbox").fileReaderJS(opts);

To see the full range of options and functionality, view the readme.

filereader.js is available under the MIT License. See the full filereader.js code or the single file raw javascript source on github.

You can see an example project using filereader.js on Instant Sprite, a browser based CSS Sprite Generator that I am working on. Try dragging images onto the body, or clicking to add multiple image files to see what is possible.