It’s Friday. Play some drums…. HTML5 style

Brian Arnold created a fun sample drum machine simulator using HTML5 <audio>.

JAVASCRIPT:
  1.  
  2. function playBeat() {
  3.         if (isPlaying) {
  4.                 var nextBeat = 60000 / curTempo / 4;
  5.                 // Turn off all lights on the tracker's row
  6.                 $("#tracker li.pip").removeClass("active");
  7.                 // Stop all audio
  8.                 stopAllAudio();
  9.                 // Light up the tracker on the current pip
  10.                 $("#tracker li.pip.col_" + curBeat).addClass("active");
  11.                 // Find each active beat, play it
  12.                 $(".soundrow[id^=control] li.pip.active.col_" + curBeat).each(function(i){
  13.                         document.getElementById($(this).data('sound_id')).play();
  14.                 });
  15.                 // Move the pip forward
  16.                 curBeat = (curBeat + 1) % 16;
  17.                 // Schedule the next one
  18.                 setTimeout(playBeat, nextBeat);
  19.         }
  20. }
  21.  

That's not all Brian is working on:

I'm also working on something like the ToneMatrix or Tenori-on (Flash and actual devices, respectively) in pure HTML/JS. It works too, but the sounds aren't exactly designed to be great together (it's currently working on a C scale) and so if you're careful, you can get some decent sound but otherwise, it'll hurt your ears.

Machsend: P2P file sharing via Browser Plus

Alex MacCaw has released Machsend, a Yahoo! Browser Plus plugin that enables P2P file transfers from inside the browser.

It showcases what can be done with a BP plugin, leaving you wish cross browser functionality.

I guess it is kinda fun to hack the browser :)

GChart 2.5: Faster, sharper, canvas-rendered, pie, line, and area charts

John Gunther has released GChart 2.5, a client-side library that adds a new canvas-rendering option for sharper, better looking, alpha-transparent, pie, line, and area charts.

John told us:

Canvas-rendering corrects GChart’s most serious visual quality limitations (including the most often mentioned problem by its users: the banded-filled pie slice).

Coupled with its existing feature set and ease of GWT integration, the canvas-rendering option makes GChart an excellent choice for those who want to add basic charts to a GWT application without a lot of fuss.

To access these features, you’ll need to plug an external canvas library into GChart (GWTCanvas in the gwt-incubator is reccommended) as described in detail in the setCanvasFactory method.

With the external canvas in place, the next step is to tell GChart you want a curve to be “continuously filled” by invoking setFillSpacing(0).

With each such continuously filled curve, GChart automatically exploits your external canvas library to improved the quality and speed of that curve’s rendering. Specifically, banded-filled pie slices become solid filled, dotted connecting lines become continuously connected, and (the biggest stretch) bar charts become area charts. See the setFillSpacing method’s javadocs for a detailed description of how each existing symbol type implements this new “continuously-filled”, canvas-powered, rendering option.

Note that GChart’s previous HTML-only rendering is still available, and is the default rendering mode if you don’t bother to plug in an external canvas.

Check out the demo

More than you ever want to see about encoding

Paul Baukaus linked to jsescape, a little form that shows escaping and unescaping across a number of encodings.

Andrea Giammarchi had his own post on encodings in a different way…. as he talked about
en-code which you can check out in action here on the page that lets you do simple encodings, especially for source code, in short order.

ASP.NET MVC Talk in Reading UK July 3rd

I’m in the UK today and tomorrow (on my way back from a trip to India for two days earlier this week), and am giving two tech talks while in town. 

The first is this evening at a London .NET User Group event.  I’ll be presenting Silverlight 3.  Unfortunately the event is already over-registered – so if you haven’t registered yet you’ll need to catch it the next time I’m in town.

The second talk is tomorrow (Friday) from 1-4pm at the Microsoft facility in Reading and is on ASP.NET MVC.  When we first announced it last week it also over-registered quickly.  Thankfully my hosts were able to get a larger room this week, though, so another 120 spots became available. 

You can register to attend the talk for free until 4pm today if you want to attend.  Hurry, though, as there are only 43 seats left (down from 57 seats when I first started writing this blog post).

Hope to see some of you there,

Scott

GeoMaker - geo locations as microformats or a map from texts or URLs

As preparation for an upcoming tech talk about Placemaker I thought it would be good to take a bit of the pain out of the geolocation service by making an interface for it. Placemaker works the following way: you post some content or a URL to it, it goes through the content or gets the content from the URL and analyzes it. It then finds geographical locations in the text and disambiguates them (for example to skip names like "Jack London" and not consider it the city London). Finally you get it back as XML.

The annoying thing is that Placemaker only support POST request and does not have a JSON output - for now. GeoMaker allows non-developers to enter some text or a URL, filter the results (using YUI datatable) to remove false positives (no system is perfect) and get the embed code for a Yahoo Map or a list of microformatted locations as copy+paste. See the screencast to get the end user experience:

Of course, every time you build something like that, red-blooded developers will ask for an API to do the same thing (and pointing them to Placemaker wasn't enough). So here it is:

http://icant.co.uk/geomaker/api.php takes two parameters: url of the web document to load and output which could be map, kml, microformats, csv, or json (with callback for JSON-P). Using this you can analyze a url in JavaScript and get the data back as an array:

HTML:
  1. <script>function geomaker(o){
  2.   for(var i=0,j=o.length;i<j ;i++){
  3.     // o[i] will have lat, lon, title and match
  4.   }
  5. }</script>
  6. <script src="http://icant.co.uk/geomaker/api.php?url=http://ajaxian.com&output=json&callback=geomaker"></script>

The Ajaxian.com output right now would be:

JAVASCRIPT:
  1. geomaker(
  2.   [
  3.     {"lat":"42.3586","lon":"-71.0567",
  4.      "title":"Boston, MA, US","match":"Boston"},
  5.     {"lat":"42.3586","lon":"-71.0567",
  6.      "title":"Boston, MA, US","match":"Boston, MA"},
  7.     {"lat":"40.7075","lon":"-106.918","title":"Clark, CO, US",
  8.      "match":"Clark, Co"},
  9.     {"lat":"42.3115","lon":"43.3658","title":"Georgia",
  10.      "match":"Geo"},
  11.     {"lat":"44.9601","lon":"7.16229",
  12.      "title":"Rey, Piedmont, IT","match":"Rey"}
  13.   ])
  14.  

Modernizr: HTML5 and CSS3 detection

Modernizr is a new library that detects various HTML5 and CSS3 features and lets you know so you can use them:

Writing conditional CSS with Modernizr

Now, once your page loads, Modernizr will run and go through all of its tests. It will automatically add all the classes to the <body> element of the page, and these classes will be along the lines of body.feature or body.no-feature, with the former indicating that the current browser supports that specific feature and the latter indicating that the browser does not support the feature.

Additionally, it will create a new JavaScript object in the global scope, called Modernizr. This object will contain properties for each of the features that Modernizr detects for, and their value will be set to TRUE or FALSE depending on the browser's support for it.

What you can do from this point on is write pseudo-IF/ELSE statements in your CSS. Let's look at an example from the Modernizr.com site itself:

CSS:
  1.  
  2. .cssgradients #main {
  3.     background: -webkit-gradient(linear, left 0, right bottom,
  4.         from(rgba(255,255,255, .82)),
  5.         to(rgba(255,255,255, 0))) 0 0 no-repeat;
  6. }
  7.  

In the above example, we're doing an "IF" condition in CSS: IF the browser supports both CSS gradients, THEN apply this background property to the #main element (instead of the original background property).

Writing conditional JavaScript with Modernizr

When leveraging Modernizr in your JavaScript, it's as straight-forward as it can be to do IF-conditions based on what the browser currently supports:

CSS:
  1.  
  2. if (Modernizr.cssgradients) {
  3.     // perform some actions you only want to
  4.     // execute if the browser supports gradients
  5. }
  6.  

We are seeing a growth in these kinds of tools and shims to get HTML5 features into developers hands. Another great site to help is the new HTML5 Doctor.

A whole lot of testing for JavaScript implementations

A couple of releases related to unit testing and JavaScript came out on the same day.

First, the JScript team posted a set of ECMAScript 5 tests…. 900 to be exact, and the focus on features that are new to ECMAScript 5.

All of the tests are released under New BSD.

Then, the V8 team announced Sputnik, a series of of 5000 tests, also under BSD. These tests aren’t for the shiny ECMAScript 5 world, but are for ECMA 262, or edition 3.

Nice to see a lot of tests out there, all under liberal open source licensing.

Firefox 3.5: The fastest fox has landed

It is great to feel the good vibes at Mozilla HQ today as we launch Firefox 3.5! It is always an interesting ride to see a browser develop, and realize how complex and large the work is.

Congrats to the browser developers out there who are working hard to make the Web better. With final versions of Firefox 3.5, Safari 4, and Chrome 2 out in the wild…. things are picking up nicely.

The Firefox 3.5 release is exciting for me because it really benefits the developers. We get Open Video, @font-face, cross site XHR, Geo Location APIs, CSS Media Queries, Native JSON, Offline support, Web Workers, and so much more.

And, the world keeps moving. I have seen some very cool things in the nightly tree, and look forward to beign around as the team works on the next great Firefox.

LABjs: Simple abstraction for loading dependencies correctly

Kyle Simpson has developed LABjs, a library that lets you define your JavaScript file dependencies, and then loads them as efficiently as possible.

Kyle told us:

This project is a simple little tool (1.6k compressed!) for being able to load javascript files dynamically. It's like a lot of similar projects where the goal is to improve the speed of page load by allowing scripts to load in parallel. The thing it does slightly differently than most others like it is it allows you to "block", which is to say, load one or more scripts in parallel, then wait for them to finish, before going on to something else, like loading more scripts.

What I wanted was a pattern where I could load scripts in parallel, just like with script tags, but also block and wait if there was an explicit ordering dependency that required it.

What most loaders fail to do well is let you define "dependencies" simply based on loading order. With regular script tags, the browser blocks for you, so you can make sure for instance that jquery.js loads before jqueryui.js. But imagine you've got 3 scripts that can download in parallel (not dependent on each other), and then two more that need to wait for those 3 to load. You can't do that with script tags, and you also can't do that very easily with a lot of the script loaders/frameworks that I've found.

Most of them rely on intrusive concepts to do "dependency" management. For instance, each child script has to "signal" (callback) that it's done loading, to the parent page. Or the parent script and child scripts have to explicitly declare dependencies using some framework or conventions. Also, some other loader libraries rely on attaching a single load callback handler for EACH script. This makes it awkward or difficult to wait for several to load at a time, before proceeding, since you as the author have to keep track of what has loaded yourself.

jsLAB lets you load pretty much any script file, whether you control it or not, with no intrusion or convention for dependencies, other than the order and blocking that you define. It keeps track of what you've asked for and what has downloaded, only loads a unique script filename once, and lets you only define your handler once for a set of scripts that will load together in parallel. The API style (with chaining) makes is very easy to convert a set of script tags in your page into code to load them, without having to worry that race conditions will cause issues for scripts loading in the wrong order if there are implicit dependencies involved.

Example

Old:

HTML:
  1.  
  2. <script src="jquery.js"></script>
  3. <script src="jquery.ui.js"></script>
  4. <script src="myplugin.jquery.js"></script>
  5. <script src="initpage.js"></script>
  6.  

New:

JAVASCRIPT:
  1.  
  2. $LAB
  3. .script("jquery.js")
  4. .block(function(){
  5.       $LAB
  6.       .script("jquery.ui.js")
  7.       .script("myplugin.jquery.js")
  8.       .block(function(){
  9.             $LAB.script("initpage.js");
  10.       });
  11. });
  12.  

In the above example, "jquery.ui.js" and "myplugin.jquery.js" can load in parallel because there's no dependencies, but they will wait for "jquery.js" to load first, since they depend on it, and then "initpage.js" will wait for all of them to load before it runs, to it makes sure all code it will call is in place, similar to a $document.ready(...) concept.

The page link above also shows a few other variations on the .script(...) signature. For instance, you don't have to do a single script() call for each file (though I think it makes thing more readable). You can pass as many scripts singularly as parameters to one script() call. You can also pass an array of scripts, and it will loop through them and load them in the same way. Lastly, you can pass in an object instead of string, and the object literal can contain "src", "type", and "language" specifications, if you want to override the defaults of "text/javascript" and "Javascript", for some reason.