hgweb viewer, canvas version

Monday, April 14th, 2008

If you want to go drawing complex graphics on the web, you have two basic options: SVG and the HTML canvas element.

My first attempt at the hgweb graphical browser used SVG. Actually, it used an unholy hybrid of SVG and HTML: the revisions themselves were drawn using absolutely positioned HTML. The arrows between the boxes were drawn using SVG. I did this for several reasons:

  • only Firefox supports drawing text into canvas elements
  • I could use DOM events to do hit-testing and navigation
  • you can select/copy/paste text in HTML

Unfortunately, the performance of the first version was not very good, and the code was very complex. I was maintaining several parallel data structures: a JS object graph, and the DOM objects for revisions and arrows. The bookkeeping code to keep data in sync was dwarfing the actual layout logic.

Instead I decided to try using canvas. Sucking out the bookkeeping code and replacing it with a custom drawing code turned out to be much easier than I expected. Now all of the data is kept in a single tree, and layout, rendering, and hit-testing are all blazingly fast.

After getting it basically working, I was able to add additional features in a matter of minutes:

  • Collision detection
  • Animation when navigating between revisions
  • Switched to a vertical layout which provides more information
  • Made arrows into curves
  • Highlight the “center” node

The disadvantages of this approach are unfortunate:

  • Only works in Firefox 3+ (needs the experimental mozDrawText API)
  • Impossible to select or copy text

check it out (my development machine, so it may go down at any time) or get the source.

Now I really promise I don’t have any more time to spend on this project. Contributions welcome!