Tag Archives: javascript

Blackletter – Unicode Abuse

Unicode is an all encompassing project, its goal is to make it possible to represent all existing documents as a series of bytes, from ancient hieroglyphics to Japanese txt-speak. Of course, with great power comes great abuse.

It turns out that Unicode includes a complete set of blackletter characters – actually two sets if you count bold. These are supposed to be used to represent mathematical symbols in old documents but nothing is stopping you from using them in Facebook posts to amuse and annoy.

You just need something that will easily convert from normal english text into suitable unicode HTML entities. Something, perhaps, like this:

The output may look like English text, but this isn’t the same as just changing the font – the characters are unrelated to the normal ASCII range. You can paste the results into most web pages (Facebook and Google+), but some will strip out anything weird like this. You may have to experiment.

(Before you try it; no, you cannot post blackletter comments on this site. WordPress doesn’t like it.)

Sadly some browsers/devices will not display the glyphs at all, if you only see a row of squares then you are out of luck (iOS devices do not work, neither will Chrome on Windows). Even if it works for you, other people may not be able to see your post.

Another drawback is that the resulting text will not be searchable using normal tools, although this may be a plus in situations you have already thought of.

The HTML5 audio tag

I have been mucking around with the audio tag as part of my quest to understand where HTML5 is going. The <video> tag gets all the press but I think there are many more opportunities to use audio in web apps. HTML5 is closing the gap between plugin-based apps (Flash, Silverlight, Java, etc) and sound support is an important part of that goal.

(Those of you who don’t care how it works should go directly to the TV Themes demo puzzle. It works best in Firefox3.6 and the latest version of Safari, although most browsers should function to some degree.)

The audio tag is pretty flexible, able to handle both long form audio (songs and spoken passages – the theme medley on the demo page for example) and short snippets of background audio (alerts, and confirmations – the demo plays one of two short tones when you type an answer. Video game sound effects are another example.) Optionally, the audio tag can provide a user interface for starting and stopping the audio, useful for playing long streams of audio. Different browsers have different ideas about how this should look, but they all function much the same way.

In theory, the audio tag is as easy as embedding an image into HTML:

1
2
3
4
<audio controls>
	<source src="music.mp3">
	You can put HTML here that will be displayed if the browser does not understand the audio tag
</audio>

However, the devil is in the details. There are two problems with the audio tag that complicate matters. The first is that only the very latest browsers support the audio tag at all. This means that if you want to provide audio that everyone can use, you are going to have a fall-back method available. Before the audio tag, people used to use Flash for this purpose and it still works. A number of sites provide simple Flash-based audio players that you can embed – I ended up using the player provided by Google.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<object codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" height="27" width="400" align="middle" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000">
	<param name="_cx" value="10583"><param name="_cy" value="714"><param name="FlashVars" value="">
	<param name="Movie" value="http://www.google.com/reader/ui/3247397568-audio-player.swf?audioUrl=http://full/path/to/music.mp3">
	<param name="Src" value="http://www.google.com/reader/ui/3247397568-audio-player.swf?audioUrl=http://full/path/to/music.mp3">
	<param name="WMode" value="Window"><param name="Play" value="0">
 
	<param name="Loop" value="-1">
	<param name="Quality" value="High">
	<param name="SAlign" value="LT">
	<param name="Menu" value="-1">
	<param name="Base" value="">
	<param name="AllowScriptAccess" value="never">
	<param name="Scale" value="NoScale">
	<param name="DeviceFont" value="0">
	<param name="EmbedMovie" value="0">
 
	<param name="BGColor" value="">
	<param name="SWRemote" value="">
	<param name="MovieData" value="">
	<param name="SeamlessTabbing" value="1">
	<param name="Profile" value="0">
	<param name="ProfileAddress" value="">
	<param name="ProfilePort" value="0">
	<param name="AllowNetworking" value="all">
	<param name="AllowFullScreen" value="false">
 
	<embed type="application/x-shockwave-flash" src="http://www.google.com/reader/ui/3247397568-audio-player.swf?audioUrl=http://full/path/to/music.mp3" allowscriptaccess="never" quality="best" bgcolor="#ffffff" wmode="window" flashvars="playerMode=embedded" pluginspage="http://www.macromedia.com/go/getflashplayer" height="27" width="400" />
</object>

Not exactly elegant, is it? Apart from being uuuuug-ly, the full URI of the sound file must be used (the audio tag can use relative paths). Also, the Flash players are not scriptable in the same way as inbuilt audio tag is, which can make doing tricky stuff like animating other content in response to the audio more difficult.

The second problem with the audio tag is the same codec problem I talked about in a previous rant (The HTML5 Video Tag’s Fatal Flaw) For legal reasons, different browsers play different formats of audio – most notably Firefox will not play mp3s while Safari will not play ogg. There is no single format that will play in all browsers except for uncompressed wavs, which are too fat to be useful except for very short snippets.

To get around this problem the audio tag allows multiple files to be specified. The first file that the browser thinks it can play will be used, but it does mean you have to encode and store multiple versions of each audio file.

1
2
3
4
5
<!-- Only one of these files will be downloaded -->
<audio controls>
	<source src="music.ogg" type="audio/ogg">
	<source src="music.mp3" type="audio/mpeg">
</audio>

The demo page also uses the audio tag to play sound effects in the background, using audio elements that do not have a user interface. For simplicity I used wav files (download from this awesome source of free effects.) Since they have no user interface, Javascript must be used to play them:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<audio id="clicksound" preload="auto">
	<source src="click.wav" type="audio/wav">
</audio>
 
<script type="text/javascript">
function playSound( )
{
	var a = document.getElementById( "clicksound" );
	if ( !a ) return;
	if ( !a.play ) return; // will exit if the browser does not understand the audio tag
 
	a.play();
}
</script>

It is all pretty simple but as always there are problems. I did not find a good way of replicating this using Flash, so browsers that do not understand the audio tag do not play these background noises. Also, Google Chrome (which has otherwise excellent support) contains a weird bug that prevents it playing the first couple of seconds of an audio file, making it useless for short sounds. Apparently Firefox3.5 had the same problem, but it works perfectly in 3.6.

I created the demo to see if the audio tag could replicate the functionality of Flash-based applications for both long-form audio and background sound effects. It does seem to be possible provided you are targeting a modern browser and are prepared to work around certain annoyances. Hopefully the next few years will see an improvement in support for audio, I can see many uses for it especially if the iPad (which does not support Flash) takes off.

Sketch This Page! Image Processing with the Canvas Tag

I have been quietly impressed with the progress web browsers have been making in recent years towards the goal of supporting a wide variety of applications. The promise of web-apps rivaling traditional desktop applications seems within reach after nigh-15 years of ballyhoo. Most recent browsers have extremely fast Javascript support and highly optimized DOMs, allowing a good level of interaction.

Of course, there a times when moving <div>s around just doesn’t cut the mustard. The canvas tag is not well used but is nothing less than a surface you can draw on using Javascript. It supports all the normal primitives (lines, arcs, fills, etc) and allows (indirect) access to the pixel data. While some people (eg: Project Bespin) are using the canvas tag in to offer extended functionality, I am busy fooling around.

Check out the fruit of my labour – Sketch This Page!.

It’s a Javascript bookmarklet that replaces each <img> element in a page with a same sized <canvas>. It works by copying the image to a temporary canvas, extracting the pixel data for some hacky post-processing, and then blatting the pixel-data onto the final canvas. The Javascript could certainly be better, but it works well enough and I am impressed with the speed.

The biggest flaw is that browsers will not allow Javascript to access the pixel data of images that are loaded from a different domain than the main page. This is a great idea from a security standpoint, but it does limit the usefulness of the bookmarklet. It would be great if Sketch This Page! worked on sites like Flickr, but sadly it is not to be.

For those interested, here is the function that actually dithers the image. I was going for a hatched look with the diagonal lines.

function generateBWDitherImage( src, dst )
{
   var srcContext = src.getContext(“2d”);
   var dstContext = dst.getContext(“2d”);

   var srcImageData = srcContext.getImageData(0, 0, src.width, src.height);
   var dstImageData = dstContext.getImageData(0, 0, dst.width, dst.height);
   
   for (var y = 0; y < dstImageData.height; ++y)
   {
      for (var x = 0; x < dstImageData.width; ++x)
      {
         var index = (dstImageData.width * 4) * y + (x * 4);
         var g = (0.30 * srcImageData.data[index]) +
             (0.59 * srcImageData.data[index+1]) +
             (0.11 * srcImageData.data[index+2]);
         if (g > 200)
         {
            g = 255;
         }
         else if (g > 150)
         {
            if (((y % 6) – x % 6) == 0)
               g = 0;
            else
               g = 255;
         }
         else if (g > 75)
         {
            if (((y % 4) – x % 4) == 0)
               g = 0;
            else
               g = 255;
         }
         else
            g = 0;
         dstImageData.data[index] = g;
         dstImageData.data[index+1] = g;
         dstImageData.data[index+2] = g;
         dstImageData.data[index+3] = 255;
      }
   }

   dstContext.putImageData( dstImageData, 0, 0 );
}

Javascript and Saved Passwords

First some facts…

Fact 1:
None of us can remember the passwords for the dozens of web sites we re all registered on. That is why web browsers all optionally store logon information and automatically fill out logon pages when we revisit a site.

Fact 2:
Web browsers do all support a special type of input control type specifically for passwords. Nothing entered into a password field is displayed, any characters are all displayed as asterisks. This prevents the password from being observed, either when it is first typed nor when it is automatically entered on subsequent visits to the page.

Fact 3:
Most web browsers allow you to type Javascript code into the address bar. This code is run in the context of the currently displayed document and has access to the object model.

Hmmmmmmmm…
Continue reading

Tax Cut Calculator

Another budget has come and gone, this one more discussed than most for it actually contains the much promised but little seen tax cuts (read the Minister’s Executive Summary for details).

Here is a little project I whipped up to calculate the amount you are going to better off when the tax cuts come into force. All calculations are done in dollars, not the blocks of cheese that seem to have become currency over the last week. The current exchange rate: 1kg of tasty cheese = $NZ16.15.
Continue reading