Quantcast

Announcing TikiChart!

I hacked up a front end to google charts api using jquery. You can play with it at TikiChart.com. It’s GPLed, so please help make it better!

Canvas3D

This video of a canvas3d/javascript demo in Firefox gives me hope. Some parts of my canvas(2d) web app runs 100x slower in Firefox/linux than Safari/OSX. It looks like they have hardware acceleration working, finally :)

Here is some info on Canvas3d in javascript.

AJAX Best Practices

I saw this banner while surfing the web:

Here, I’ll save you $1300:

Best Practices for AJAX content development, rule #1: When developing AJAX web apps, don’t waste your time trying to work around Safari’s many DOM/Javascript/Canvas bugs. Instead, force your mac users to upgrade to Firefox*.

*Corollary to rule #1: At least force them to upgrade to a nightly build of WebKit, but even then, you’re walking into a very buggy minefield.

I would have saved a few weeks of development time if I had followed rule #1 sooner.

Firefox: It sucks, but it sucks much less.

How to render text using HTML Canvas

I’ve been using HTML5 Canvas for a few web apps, and for the last year I’ve been avoiding rendering any text because Canvas lacks text support. Over the last year, several people have come up with workarounds.

  • Firefox decided to add a non-standard method called drawWindow(), which lets you composite a hidden iframe with html text.
  • The TextCanvas project adds a drawString method to the canvas api, which positions a HTML element on top of the canvas.
  • The Variable Width Canvas Fonts project pre-generates an image containing characters at known locations and then uses drawImage to display the necessary characters.
  • The very cool CanvasPaint project went nuts and implemented vector fonts in canvas! (more info here)
  • None of the above links work in Safari. Despite being the original developers of Canvas, Safari’s Canvas support is extremely buggy. Things work better with the nightly builds, but even then, many things are broken.

I’ve been thinking about giving up on supporting Safari completely, and maybe trying out dojo’s gfx 2D graphics API, which has text support but uses SVG/VML instead of Canvas. For the time being though, I found a silly workaround. Since I only need to display numbers, I can just create 10 pngs, one for each digit. Here is a bash script that creates the number pngs using ImageMagick:

CODE:
  1. for ((i=0;i<10;i++)); do
  2.      convert -size 75×100 xc:transparent -quality 100 -font Courier-Bold -pointsize 144 -fill green -draw “text -5,95 ‘$i’” g$i.png;
  3. done

Here’s a blurry screenshot of how it looks:
6.jpg

MSPaint implemented using HTML Canvas

mspaint.pngYou know how I’m always talking about how HTML Canvas is going to enable all kinds of new and interesting web apps? Well, someone implemented MSPaint in Javascript using Canvas! You KNOW someone out there is working on a Canvas version MacPaint… or how about a Canvas version of System 7???

Twitter Implements Callbacks!

Less that one day after I called them on the phone, the good folk at Twitter have already pushed out callback support, and we’re now using it on this site!

Here is the email I just got:

Hi!

Cool stuff you are working on =)

I’ve just deployed callback support for the api:

http://twitter.com/statuses/user_timeline/6760.json?callback=myCallback

If you have any questions, etc.. let me know.

Ciao!
Florian

Note that this URL is different from their standard badge URL.. Thanks Twitter!!!

Here is a short tutorial on how to add your twitter badge to your webpage, in such a way that it doesn’t slow down the initial page load.

1. Put this html snippet somewhere on your webpage. Replace USERID with your actual twitter numeric id.

HTML:
  1. <div id=“my_twitter_status_USERID”><img src=“spinner.gif”></div>
  2. <div id=“my_twitter_status_time_USERID”></div>

2. Add an onload attribute to the BODY tag in your html:

HTML:
  1. <body onload=“initTiki();”>

3. Add three javascript functions to the HEAD portion of your webpage:

JavaScript:
  1. <head><script type=“text/javascript”>
  2. function twitterCallback(obj) {
  3.     var id = obj[0].user.id;
  4.     document.getElementById(‘my_twitter_status_’ + id).innerHTML = obj[0].text;
  5.     document.getElementById(‘my_twitter_status_time_’ + id).innerHTML = ’sent ‘ + obj[0].relative_created_at;
  6. }
  7.  
  8. function twitterStatus(url) {
  9.     var twitScript  = document.createElement(“script”);
  10.     twitScript.setAttribute(“type”, “text/javascript”);
  11.     twitScript.setAttribute(“src”, url);
  12.     document.getElementsByTagName(‘head’)[0].appendChild(twitScript);
  13. }
  14.  
  15. function initTiki() {
  16.     twitterStatus(‘http://twitter.com/statuses/user_timeline/USERID.json?callback=twitterCallback&count=1′);   
  17. }
  18. </script>
  19. </head>

That’s it. If you want to be sure that your badge is very up-to-date, you can get around some JS caching issues like by adding a random parameter to the url. This is more of an issue for IE users, and since we don’t know any of those, and we don’t like waiting, we don’t use this technique. Here is an example, tho:

JavaScript:
  1. function initTiki() {
  2.     var rnd = ‘&rnd=’ + Math.random();
  3.     twitterStatus(‘http://twitter.com/statuses/user_timeline/USERID.json?callback=twitterCallback&count=1′+rnd);   
  4. }

TwitterTronix

Want to know why Web 2.0 is sooo much better than Web 1.0? It’s because I just talked to Jack from Twitter ON THE GODDAMN TELEPHONE, and he’s says they are going to implement a callback param for their web API, just because I asked :)

Web APIs that return JSON are great, but not all browsers fire onload events for script elements, so if you want to load the JSON asynchronously/dynamically/on-demand, you need to think of something else.

One good way of doing this is wrapping the returned JSON in a callback function, which is best done by adding a callback param to the API, as shown below:

http://twitter.com/t/status/user_timeline/6760?count=1&callback=myCallback

This returns the exact same JSON, just wrapped in a call to your callback function:

myCallback([{"user": {"name": "rajbot", "id": 6760, "screen_name": "rajbot"}, "text": "enjoying the second summer :)", "id": 35084, "relative_created_at": "about 3 hours ago", "created_at": "Mon Sep 25 22:20:49 UTC 2006"}]);

Very simple, and it works in all browsers, so it’s wonderful that Twitter is going to update their API. But what if you are impatient like us and want to use this technique RIGHT NOW? Well, if you don’t care about error checking, you can wrap the existing Web API with three lines of your favorite scripting language:

PHP:
  1. <?php
  2.     $id = $_REQUEST[‘id’]
  3.     $result = file_get_contents(“http://twitter.com/t/status/user_timeline/{$id}?count=1″);
  4.     echo “twitterCallback($result);”;   
  5. ?>

We now display the twitter status in the header. Since we call the Twitter Web API after the entire page finished loading, our readers no longer have to wait for the Twitter servers to respond before reading our babble. We expect this bump up global productivity by several minutes!

Update: Twitter has implemented callbacks! That was fast :)

Whither spidermonkey?

A current project of mine involves some JavaScript hacking. Every time I deal with JavaScript I lament its lack of distribution as a programming language platform. A listing of debian packages for keyword “lisp” (yes, lisp!!!) gets 283 hits on debian/intel, and 22 hits on fink. A listing of debian pages for keyword “javascript” gets 58 hits on debian/intel and 4 on fink (and none of the fink hits appear to be programming packages).

Is everyone just using js.jar now from the rhino project? I wish spidermonkey was more popular in it’s own right. But for years now the spidermonkey page has said the same thing: “The core SpiderMonkey engine can be found in mozilla/js/src. The stand alone interpreter can be built using Makefile.ref”.

Hey guys, make a debian package already!

Link to SpiderMonkey project page.