Code snippets, tech tricks and other bits and bobs

jQuery .width() may not return pixels if element is hidden

jQuery 1.7.1

This got me for a while - while there is some discussion of .width() not behaving properly, only this stackOverflow [new window] hinted at the fact I wasn't mad - all the others being sparse on examples, or poorly worded, leaving me wondering.

But, hell, I'll give it a go, I thought, and it turned out that I was suffering exactly this:

The jQuery documentation clearly states:

The difference between .css(width) and .width() is that the latter returns a unit-less pixel value (for example, 400) while the former returns a value with units intact (for example,400px). The .width() method is recommended when an element's width needs to be used in a mathematical calculation.

Ok, fair enough.

But I had {n} columns in a graph, containing a bar in each. The columns are set to (100 / {n})% width while the graph is being populated - and most importantly here, hidden.

I wanted to give my bars a little padding in pixels, so I needed to get the column size in pixels. In my example I had 4 columns, width 25% each, which worked out as 88px. Calling $('.column).width() -6 I expected to get 82, but got 19 instead.

One stackOverflow suggested that you should use an id instead - not ideal, as I don't always know what the ids will be and don't want to bother storing one just for the sake of the calculation. But I tried it with this case as I did know the ids - and it still didn't work.

So I moved the column .width() call to after my .show() call - and magically, it returned 82.

Call it an 'undocumented feature', call it a bug, but watch out for it!

I ought to report this, but as of writing the jQuery trac is down. MySQL has gone away apparently :'(

Filed under  //   Javascript   jQuery  

Fully cross platform video - HTML5 for iPad/iPhone with Flash fallback for older browsers

If, like me, you are a bit excited by the advent of native video and audio in HTML5, you are also probably apprehensive about cross platform support and backwards compatiblity.

The expolsion of iPlatforms without flash support is causing concern for many site owners - having spent enormous amounts of time and money creating and converting their videos to FLV for Flash video players, a lucrative demographic is now excluded from their content. HTML 5 promises a solution to this, but how best to implement it, and how to do it cheaply without investing in new software for conversion and delivery?

Luckily there are nutters out there who are already putting the hours in to create the solutions utilising Javascript to handle as many situations as possible..

I've tried two so far, and both have their pros and cons, as is to be expected.

It's a pretty complicated sphere, and I'm not going into details here - GIYF, if you need to know more, but the information here should get you up and running in no time. Build either (or even both) solution into your own copy of HTML5 Boilerplate and I reckon you are really onto something...

VideoJS [★★★]

Simple, lightweight and easy to implement, VideoJS is a great solution for a single item player. I had this up and running in no time, with my eyes closed.VideoJS is either developed by or has been purchased by Zencoder. Thanks for that guys - cunning way to promote your paid-for encoding service! Makes sense really - make it easy for people to use video online and increase demand for your services...

http://videojs.com [new window]

Open Standard Media Player (OSM Player) [★★]

Complex, heavy, trickier to implement and sparsely docuemented, yet despite all this, based on my experience the jQuery driven OSM Player has massive potential. It's much more feature rich, comes with a PHP implementation and if you are already using jQuery it's nice to have something that fits in with your existing framework. This is one to keep an eye on in my opinion. I'd love to see all its parameters properly documented, but if you are prepared to dig under the hood it could be well worth the effort.

http://www.mediafront.org/project/osmplayer [new window]

[update 20110223-1140]

jPlayer [★★★★]

More features than VideoJS? Please.
More documentation and simpler implementation than OSM? Ta very muchly.
jQuery based? Why, ambassador... *flutters eyelids*
Worthy contender for the crown, with a few issues (IE is supported but why I can't get it going in my initial implementation I do not yet know), jPlayer is, in general, right up my street. I like the coding style. The documentation is a bit spartan, but hardly required. Support forums are in place and in use. And their website is reasonably attractive and pleasant to use. All things that mark OSM down heavily, which considering OSM's features is a tragedy. Get stuck in with jPlayer I say.

Note that for jPlayer's Flash fallback to function it requires H.264/MP4 files to have an .m4v file extension - it doesn't seem to support FLV video oddly for a flash player, but that does save you converting one more format.

http://www.jplayer.org [new window]

[/update]

[update 20110720-1625]

Projekktor [★★★]

Thought I would add this one in quickly (especially as this is one of my more popular posts) - I needed a player with easy YouTube support, and Projekktor did the job nicely. Very easy to implement, with some advanced features including playlists, skins and pre- and post-roll ads, with reasonable documentation. Well worth a shot if you want to get up and running quickly...

http://www.projekktor.com/ [new window]

[/update]

Converting your videos - Miro Video Converter

The important thing to remember is that you now need to provide at least THREE formats for every video - MP4, OGG and FLV.
This is because Safari (essential for those iPlatforms) and Chrome support MP4, Firefox and Opera support OGG. Oh my lord. Format wars? More on that in a minute.
The third format (FLV) is for older or obscure browsers. Which includes the latest Internet Explorer, because it is obviously both old and obscure. Or just plain awkward. Take your pick.

[update 20110223-1223]

For more on the format bunfight see my blog post on the subject

[/update]

Now assuming you already have all your old FLV videos, one quick and dirty solution is Miro Video Converter - this is a free and extremely simple utility that will output Theora (OGG) and H.264 (MP4/M4V) file. If you need to do batch conversions you will need to hunt out a better solution - as I am only testing my first implementation for a site with just a single video I haven't looked into one yet, but I'm sure it will be coming up soon! Also, for MP4, Miro only seems to do single-pass encoding, so you may want to look at an alternative (like Avidemux) for two-pass encoding.

http://www.mirovideoconverter.com [new window]

There is a third format for HTML 5 - .webm. Say whaaat? It's a format for Google's open source codec VP8. It is supported by Firefox, Chrome and Opera currently, and if Safari adds support (and IE when they decide to join the HTML 5 video party) then it will solve the format wars problem. Of course whether Apple and Microsoft are comfortable with everyone using Google's video codec is something that remains to be seen.

You can also convert your files to .webm with Miro Video Converter.

Online Conversion

If you are regularly converting large numbers of files, or want a solution to integrate with a CMS then a service like Zencoder [new window] is worth looking into, and I have had very satisfying results.

Alternatively, if you are running a *nix server and a willing to throw the resources at processing video yourself, you can check out ffmpeg [new window] - installation and configuration can be challenging, but there are people out there who will do it for you at very reasonable rates. If you are processing a lot of videos though, this will impact on your overall server performance, so bear this in mind.

Serving OGG files

Many web servers are not configured to correctly server OGG or WEBM files - this can easily be corrected by adding 'AddType video/ogg .ogv ' and 'AddType video/webm .webm' to your .htaccess file. For safety's sake you might want to add MP4 too:

AddType video/ogg .ogv
AddType video/mp4 .mp4
AddType video/webm .webm

Filed under  //   Codecs   HTML5   Javascript   Video   jQuery  

Instant transparent PNG generator v0.2

Earlier, I needed a semi-transparent png. I couldn’t be bothered to fire up Photoshop, couldn’t be bothered to steal one from another project, couldn’t find a png maker online, and yet I could be bothered to write an app to do it for me and share it with the world. F'kn stupid huh?

I’ve still not done the task I wanted it for in the first place!

The project utilises jQuery 1.4.3, jQueryUI 1.8.6 slider and Stefan Petre’s jQuery Color Picker plugin:

jQuery: The Write Less, Do More, JavaScript Library

jQuery UI - Slider Demos & Documentation

ColorPicker – jQuery plugin

Assistance with png generation garnered from this Codecall Forum post by AfTriX

This is a first, but fully functioning, release. As such, it still requires a decent user interface, and the code needs commenting, but it’s pretty simple stuff, thanks to Jquery. The png creation (once you get it to create an initial transparent png, which is much harder than documentation would suggest) is very simple, and achieved in just a handful of lines.

[UPDATE 1321-13112010]

The interface has now been fully styled for a much more pleasant appearance, and to match the blog. It’s quite CSS3 heavy for the spankier effects, so of course looks best in an up to date browser.

[/UPDATE]

I started by collecting the libraries and jigged the directory structure to my liking:

root
 |- inc/
 |   |- js/
 |       |- colorpicker.js
 |       |- css/
 |       |   |- colorpicker.css
 |       |   |- ui-darkness/
 |       |       |- images/
 |       |       |  |- {jQuery UI images}
 |       |       |
 |       |       |- jquery-ui-1.8.6.custom.css
 |       |
 |       |- images
 |       |   |- {colorpicker images}
 |       |
 |       |- jquery-1.4.3.min.js
 |       |- jquery-ui-1.8.6.custom.min.js
 |
 |- png-maker/
 |   |- index.php
 |   |- images/
 |   |   |- checker.gif
 |   |   |- preview_bg.gif
 |   |   |- {other non-critical template images}
 |   |- png.php

First up is the form and UI – this is actually html and Javascript, but I gave the file a PHP extension for forward compatibility.

index.php

As this code contains a complete HTML page, it’s a bit difficult to include in the blog, so here it is on paste bin:

http://absolutedisaster.pastebin.com/CjCkrHBk

colorpicker.js

A small hack is required to get the colorpicker to populate the hidden form fields with RGB values – there are of course other ways to do this, but as this hack is unobtrusive, and being jQuery will fail gracefully if this version of the plugin is used anywhere else, it seems the tidiest way to do it to me.

l.28 – 34 <<

fillRGBFields = function  (hsb, cal) {
    var rgb = HSBToRGB(hsb);
    $(cal).data('colorpicker').fields
        .eq(1).val(rgb.r).end()
        .eq(2).val(rgb.g).end()
        .eq(3).val(rgb.b).end();
},

l.28 – 40 >>

//dMb - 12/11/2010 Hacked for PNG generator
fillRGBFields = function  (hsb, cal) {
    var rgb = HSBToRGB(hsb);
    $(cal).data('colorpicker').fields
        .eq(1).val(rgb.r).end()
        .eq(2).val(rgb.g).end()
        .eq(3).val(rgb.b).end();
    //start modification
    $('#r').val(rgb.r);
    $('#g').val(rgb.g);
    $('#b').val(rgb.b);
    //end modification
},

And the second half of it is the png script

png.php

if($_SERVER['HTTP_REFERER'] != 'http://absolutedisaster.co.uk/png_maker/'){
    header('HTTP/1.1 403 Forbidden');
    echo '403 Forbidden';
    exit;
}
$w = $_POST['w'];
$h = $_POST['h'];
$r = $_POST['r'];
$g = $_POST['g'];
$b = $_POST['b'];
$a = 127 - round($_POST['a'] * 1.27);
$an = round($_POST['a'] * 2.55);

$png = imagecreatetruecolor($w, $h);
imagesavealpha($png, true);
imagealphablending($png, false);
$transparent = imagecolorallocatealpha($png, 200, 200, 200, 127);
imagefill($png, 0, 0, $transparent);
$fill = imagecolorallocatealpha($png, $r, $g, $b, $a);
imagefill($png, 0, 0, $fill);
header( "Content-type: image/png" );
header('Content-Disposition: attachment; filename="w' . $w . 'h' . $h . 'r' . $r . 'g' . $g . 'b' . $b . 'a' . $an . ' .png"');
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
imagepng( $png );
imagedestroy( $png );

The script in action

http://absolutedisaster.co.uk/png-maker

 

Source files

The custom jQuery UI files have been further reduced as much as possible – uneccessary images and CSS rules have been removed. This means this version of the UI plugin may not be suitable for use in other projects unless you just want a simple slider as in this case. Also the colour picker background image and css have been modified to simplify the interface slightly.

I’m releasing this as GPL – feel free to install, modify, whatever, as long as it is not sold or otherwise charged for, and, wherever you use it, be good enough to give me credit, retain my credits in the files and drop me a line.

http://absolutedisaster.co.uk/png-maker/png-maker_v0.2.zip

Filed under  //   Javascript   PHP   PNG Generator   jQuery