Update on the simplistic 3D renderer for Canvas 2D: TinyDim

Demo

You control the demo mainly by left/right dragging the mouse, but some basic, unoptimized support for keyboard navigation is in there as well (Arrow Key/PgUp/PgDn). If you click on a face it will light up briefly and you can now enter a new color in the fields below the canvas.

A guy named Luke recently posted a comment on a three year old post that I honestly had mostly forgotten about: “Canvas 3D Renderer updated“. It was about one of the first Javascript programs capable of rendering a file exported from a 3D program without a plugin.

There are by now several such engines using Canvas 2D, a good deal of them more advanced, faster and better supported. However: TinyDim, which was the name I used when I compiled that sample into a sort of generic Javascript library has its advantages in being small, simple, easy to understand and therefore easy to hack and extend.

So this is a sort of update what has happened since then: I’ve actually used TinyDim sometimes and it has received some level of basic optimization at the code level (it’s still missing any structural optimizations like caching or viz-areas), but I never got around to post about it. It now has support for one global light and has its own mouse navigation class for when you just want to view a static 3D model. Support for colored faces is still only hacked in with a proprietary format (although that would be easy to change, you just have to write a MAT file parser) and It can return the face you’ve clicked on.

So, if you want to hack in texture support using this technique or anything else, be my guest 🙂

Dock-style zooming icon bar in pure HTML+CSS

Update: The initial post mentioned transforms, which were used in the initial version, but later replaced by simple absolute positioning.

Demo

An OSX-style icon bar in pure CSS, without any Javascript. Not much to say except: Enjoy 🙂

This sample uses CSS transitions, meaning that it requires a Firefox 4 preview build.

Webkit manages to do … something (Webkit tries to do some transitions in sequence instead of simultanously). Opera apparently has no support for pointer-events in HTML yet.

Try to disable the stylesheet (View/Page Style/No Style in Firefox): The document remains usable. Ugly, but usable.

Fixing HTML5 YouTube’s fullscreen playback with AdBlock+

I haven’t used AdBlock+ for quite a while… ever since I entered the realm of Flash-less web browsing thanks to Adobe’s inability to produce a 64 bit Windows version of the Flash plugin. However when Beta 1 of Firefox 4 was released I had to answer the question “Does AdBlock+ work?” quite often (the nightly does), so I more or less had to install it.

I used the opportunity to get rid of the biggest annoyance of YouTube’s HTML5 player: the broken full screen mode. YouTube overlays the video with a transparent div in order to block users from right-clicking on a video, since this offers the option to save the video (YouTube’s videos may be free, but they are still copyrighted and you don’t automatically get the right to distribute them).

Getting rid of this overlay with AdBlock+ is easy since it has a unique class attribute: “video-blocker”. Just Go to AdBlock+ preferences window (Tools -> Adblock Plus Preferences…), click “Add filter…” in the lower right and enter the selector “youtube.com##.video-blocker” (without quotes). This hides the overlay and you’re now free to right click on any YouTube HTML5 video to access the fullscreen option.

Here’s a link to the Coraline trailer: Try it. Link.

Using the real full screen mode instead of YouTube’s normal pseudo full-screen mode also means that Firefox can now use hardware acceleration (via OpenGL and Direct3D), even if you don’t have Direct2D enabled. Even my old laptop can play HD WebM video this way.

Texturing with Transform, without WebGL or Canvas

Update: I’ve checked it in Firefox 3.6.6 and to my surprise it works perfectly.

Demo

With the maturing of Direct2D support in Firefox I feel that it’s time to revisit transformations. Transformations let you rotate, skew and so on arbitrary elements on a page. They are relatively slow to do in software but really fast in hardware.

After a long discussion that I had recently, I should point out that this is a DEMO, meaning that it’s supposed to show what you CAN do with HTML+Transformations, rather than what you SHOULD do. A demo is not useful on it’s own, it’s just meant to illustrate a concept.

In this case, it shows a very simple approach to doing free-form deformation of bitmaps. I tried it in pure HTML+JS+CSS here, but the concept and quickly and easily be applied to other drawing systems like Canvas2D, where it could be used to provide a fallback for WebGL.

Aaah, the web in its purest form

I don’t know about you, but right now, I’m having a blast using the web. Even more than I used to have. The reason:

Mozilla has started releasing x64 builds of Firefox. And I’m having a lot of fun using it, but probably not for the reasons you’d imagine.

First off, the x64 builds are not really any faster yet than the standard x32 builds, due to some optimizations not working on x64 yet. And even then, the speed difference would probably be negligible. X64 is no magic bullet that suddenly makes an application twice as fast.

So why am I having so much fun? Because my plugin list is EMPTY. ZIP. NADA. For the last two months or so I’ve been surfing on pure Firefox goodness. There simply are no plugins for Firefox x64 builds available yet. I’ve been using Flashblock before, but even with Flashblock, the Flash plugin still gets loaded… it’s just removed immediately afterwards.

Now, I like watching a YouTube video every once in a while as much as the next guy and I’m glad that I still have x32 builds available for when YouTube has no WebM available (hint: create a link to your x32 firefox.exe and an empty directory somewhere on your HDD, then modify the link to read “firefox.exe -no-remote -profile c:\my\directory”, so you can start it without having to close your normal Firefox first) , but separating video browsing from my main browsing experience has increased the quality of my browsing experience tremendously, to the point where it outweighs the inconvenience of launching another Firefox instance by a wide margin.

(Yes, I could have disabled Flash before, but just like the rest of the world I never imagined that it would have such an impact on my browsing experience).

You can find current Firefox x64 trunk builds at ftp://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-mozilla-central/ , labeled win64-x86_64

SVG Animation Stick Demo

Not much to say about it other than I needed a quick, simple and working little thing to demonstrate SVG animations … I made a simple little stick man that leverages SVG’s tree structure to create a simplistic bone model and animated it so that it worked in Firefox (which means leaving out anything fancy like animations with more than just a start and an end value).

It’s not much, but I thought I’d post it in case somebody else wants to illustrate the same thing:

http://tapper-ware.net/data/devel/web/apps/SMIL.Stickman/index.svg

A shorter way to do Math.floor – A little known trick

Nothing groundbreaking, but someone just handed me code that was filled with Math.floor calls. While this doesn’t automatically slow down your code the way it used to, thanks to better Javascript engines, it’s still ugly as hell to look at.

Now, those people who like to put wavy brackets on individual lines will probably start shouting again, but once you’ve gotten used to it, this is actually a good deal more readable, since it shortens the code considerably, while still having a “unique look” that you’ll be able to identify quickly

Instead of
Math.floor(foo)

You can simply do a bitwise OR with 0:
0|(foo)

The reason this works is that any bit operation causes the number to be converted to a signed 32 bit integer. While this isn’t strictly the same as what Math.floor does, it will give you the same result at least for positive 31 bit integers. For negative ones you get something a little different (but typically far more useful), namely the integer part (-3 for -3.7) instead of the the highest integer smaller or equal to the given number (-4 for -3.7).

@Chromium Team: please provide usable error messages

Reorganizing a project I rewrote a part that previously included a source file via a script file to include it via XMLHttpRequest and BOOM, my code suddenly imploded on Chrome during local testing.

What’s so bad about it is that it imploded with a cryptic error message “XMLHttpRequest Exception 101” which means a NETWORK_ERR has occured(a fairly broad error state that basically covers everything that has to do with loading).

I figured that this could be a security restriction and was able to find the appropriate bug #37586, but really: you don’t want to have your developers jumping through such hoops just to find out what an error message means. A simple error description such as “Security Error: Document may not request data from file:// protocol” would have spared me and probably a lot of other people a lot of searching.

In case you’ve encountered the same issue: The solution is to disable file:// protocol restrictions with the –allow-file-access-from-files command line switch.

A pattern for Javascript OOP that I actually use

Apparently a few people were pretty irritated the last time I posted about what you can make Javascript do (+foo instead of foo() for calls) so today I thought I’d post about a pattern that I actually use regularly. Of course, as with any pattern there are good reasons not to use it. Most of all:complexity… for example you may not be able to make your favourite development environment understand it. Speed shouldn’t be an issue though: It adds one entry to the name lookup tree, but that shouldn’t even really be measurable.

When you do OOP Javascript you’ll often want to add a lot of stuff to the prototype of a constructor. Often people use object notation to get around having to type Foo.prototype.bar=… over and over again. Problem is: This replaces the prototype, so if you’re using inheritance it won’t work. You’d overwrite the inherited prototype:

var BaseCtor=function(){};

var FailedInheritanceCtor=function(){};
FailedInheritanceCtor.prototype=new BaseCtor;
FailedInheritanceCtor.prototype={
   foo:0,
   bar:1
};

alert((new FailedInheritanceCtor) instanceof BaseCtor); //false

var WorkingCtor=function(){};
WorkingCtor.prototype=new BaseCtor;
WorkingCtor.prototype.foo=0;
WorkingCtor.prototype.bar=1;

alert((new WorkingCtor) instanceof BaseCtor); //true

So, you need to do assignments. Of course you could use a function to do them, but that’s one more unnecessary and ugly function call. Or you could use a temporary variable to point to the prototype… but unless you can use Javascript 1.7’s “let” statement that would mean contaminating the current scope. You could wrap it into an anonymous function, but that hardly improves readability.

All of this can be avoided by using the poor man’s “let” (or poor browser’s: your choice): with()
With pushes an object into the name lookup tree… the nice thing is that this object can be created right inside that statement

with({hello:"world"})
   alert(hello); //world

And we can do the same stupid trick with the prototype property:

var BaseCtor=function(){};

var WorkingCtor=function(){};
WorkingCtor.prototype=new BaseCtor;
with({_:WorkingCtor.prototype}){
   _.foo=0;
   _.bar=1;
}

or like this if you want it more compact (I never do that though):

var BaseCtor=function(){};

var WorkingCtor=function(){};
with({_:WorkingCtor.prototype=new BaseCtor}){
   _.foo=0;
   _.bar=1;
}

There. simple. I usually combine it with a variable _ inside the methods to get to this, but that may feel wrong to you.

var BaseCtor=function(){
   var _=this;
};

var WorkingCtor=function(argFoo){
   var _=this;

   _.foo=argFoo;
};
WorkingCtor.prototype=new BaseCtor;
with({_:WorkingCtor.prototype}){
   _.foo=0;
   _.bar=function(argFoo){
      var _=this;

      alert(_.foo);
   };
}

(new WorkingCtor(1)).bar(); //1

Offering Bookmarklets with icons

Update: This doesn’t work as intended anymore. A new article offering an alternative method that works for modern Firefox versions has been posted here.

Note: this is tested only in Firefox. It works perfectly there, but in other browsers you may either get the icon only temporary (if the bookmark icon cache is part of the normal cache) or no icon at all. However it won’t break anything anywhere, so that’s no reason to not use it.

I investigated this a while back and it’s really quite simple, but apparently few people are aware of it:

First of all (in case you don’t know what a bookmarklet is): Bookmarklets are tiny Javascript programs that you store in Bookmarks which when you open the bookmark will run on whatever page you are currently viewing… for example copying a snippet from an article and pasting it into your blog or highlighting images or … well just about anything that a website can do. Pretty much any popular site (Google, Facebook, …) offers bookmarks for various purposes.

The problem is that apparently very few Bookmarklet developers know how to provide icons. Hopefully my little post can change that at least a bit 🙂

It’s really quite simple: Bookmarklets usually have this form:

javascript:alert(“My functionality”);void(0);

Most people put that void(0); there automatically, but it’s important to realize what it actually does: It prevents the code from returning anything. Why do we do that? Because otherwise we’d trigger another behaviour of javascript: urls. Something that I usually like to call “poor man’s data: urls”. You see, anything a javascript url call returns is processed as HTML. So javascript:”<!DOCTYPE html><html><head><title>Hello World</title></head><body>Hello World</body></html>”; actually sends you to a HTML document.

So, let’s recap: A javascript: url can either be a bookmarklet or a document. Well, that’s not quite correct, it’s actually always both, we just use one of these functions at a time. We can actually have both at the same time in various ways, the one that’s most important in our case is that we want the javascript: url to behave like a document when the user clicks in on the webpage, but like a bookmarklet after the user has added it as one. The reason being that documents can have icons. And since the url will be identical, so will the bookmarklet.

So first set up a document javascript: url with an icon:

javascript:'<!DOCTYPE html><html><head><title>Hello World</title><link rel=”icon” type=”image/png” href=”http://www.tapper-ware.net/devel/js/JS.Bookmarklets/icons/next.png” /></head><body>Hello World</body></html>’;

Go ahead, click it 🙂 . You’ll see a nice little play button as icon. Drag the title bar onto the bookmarks toolbar and you’ll see that it retains the icon and as an added bonus the title. Don’t worry about the HTML code bloating up your Bookmarklet, we won’t have to include it directly in the final version, but it’s easier to understand this way.

So, now we need a branch so that it will show the content only when clicked on the original page. Again, there are different ways, for now we’ll just stick with the easiest one of checking for a variable that we are reasonably sure will only exist on the original page:

javascript:window[‘bm.dummy@tapper-ware.net’]=true;void(0);

javascript:if(window[‘bm.dummy@tapper-ware.net’]){ ‘<!DOCTYPE html><html><body>My document</body></html>’; }else{ alert(‘My functionality’); void(0); }

Now, we only need the document content if the variable exists, so we can use it to transport the content instead of including it literally in the bookmarklet, bringing the size of the Bookmarklet down dramatically and freeing us from the requirement to have really compact HTML:

javascript:window[‘bm.dummy@tapper-ware.net’]='<!DOCTYPE html><html><body>My document</body></html>’;void(0);

javascript:var bmi=window[‘bm.dummy@tapper-ware.net’]; if(bmi) bmi; else{ alert(‘My functionality’); void(0); }

You could of course also introduce some randomness into the id if you’re afraid websites will try to block it, I’ll leave that up to you.

At the end of the day, you’re whole bookmarklet could then look something like this:

javascript:

var id=’bm.next.’+((Math.random()*9999)|0)+’@tapper-ware.net’;

window[id]='<!DOCTYPE html><html><head><title>Next</title><link rel=”icon” type=”image/png” href=”http://www.tapper-ware.net/devel/js/JS.Bookmarklets/icons/next.png” /></head><body>This is a bookmarklet. Drag its tab to your bookmarks toolbar to add it. Click the resulting button on any page to automatically find links containing the word next</body></html>’;

document.location=’javascript: if(window[“‘+id+'”]){window[“‘+id+'”]; }else{ (function(){ var f=function(e){ return !!(/next/i).exec(e.textContent)}; var l=document.querySelectorAll(“a”); for(var i=0;i<l.length;i++) if(f(l[i])) document.location=l[i].href; })(); void(0); }’;

void(0);

There are numerous way to automate this or make it prettier, but I’ll leave that to you. So long 🙂