Kwot JS

Remem­ber Kwot, my Flash quote viewer? I pub­lished it back in Decem­ber 2008.

It is a mix of Flash (most part of it), JS (for the add form and its com­mu­ni­ca­tion with the main UI) and PHP (CRUD logic). Read the blog post for more details on it.

I recently started look­ing at JavaScript frame­works and tools, prob­a­bly like most Flash devel­op­ers. Not because Flash is dead, but because the more tools you mas­ter, the bet­ter you are. And because yes, every­one is ask­ing for JS and CSS3 these days. After some inves­ti­ga­tion I decided to give Backbone.js a try. And re-writing Kwot from scratch with it seemed like a great exer­cis­ing opportunity.

So here its: Kwot JS!

It should work really well on Safari, OK on Chrome, not-that-perfect on Fire­fox and poorly on Inter­net Explorer. You were look­ing for a rea­son to con­tinue using Flash for build­ing “expe­ri­ence sites”? There you have it: com­pat­i­bil­ity. Kwot JS relies on CSS3 trans­forms to allow this per­spec­tive view on quotes, and on prop­erty tran­si­tions to ani­mate the quotes’ col­ors. Of course this doesn’t work in all browsers!

Now, about Backbone.js. The framework’s require­ments and logic are good, but com­ing from an AS3 world mostly every­thing looks odd, for bet­ter or worse. Note this is my first project with it and I might have missed some good prac­tices or handy tips.

The good thing is its per­sis­tence layer. In Kwot, quotes are stored in a data­base, I sim­ply wrote a sim­ple REST­ful API with Slim (try this PHP frame­work: win) and con­nected it to my Model classes. That’s it, it just works. Underscore.js’ tem­plat­ing sys­tem is hand­some, too. Never used that before, cool stuff.

The bad things are, as far as I’m concerned:

  • No strong typ­ing. Of course this isn’t Backbone’s prob­lem, but rather JS’ one. On this par­tic­u­lar point your IDE can help, but you won’t get run­time errors.
  • The “this” key­word. You always end up with plenty of lines all start­ing with a “this.something”. It frus­trates me.
  • Scope issues: when lis­ten­ing to events you pretty much always have to use Underscore.js’ bind method in order not to lose your infa­mous “this” scope. I don’t like that.
  • The MVC pat­tern. If you ask me: it sucks. I’m no inte­grist but I wouldn’t have called what Back­bone pro­vides MVC. I was always won­der­ing “who should do that?” and never really came up with a sat­is­fy­ing answer.

Over­all the learn­ing curve is pretty steep, I think it took me less time to write this ver­sion than the Flash one, but I’m a 3 year more mature devel­oper. Also, when I wrote the Flash ver­sion I didn’t really know where I was going and I kept expe­ri­enc­ing with con­cepts and ideas to see what would look best.

On a side note the Flash ver­sion uses Neu­tra, whereas this one uses Ques­trial (hosted and served by Google Webfonts).

Tell me what you think, both about the app and the framework!

La Classe Américaine – Android

Hey, fel­low english-reading vis­i­tor, this post is going to be in French! Hope you don’t mind.

Si comme moi vous ne pou­vez pas vous empêcher de dire “flim”, “ouiche” ou encore “un pour l’argent, deux pour le spec­ta­cle et trois pour le cail­lou”, cette appli­ca­tion est pour vous.

Après une semaine de vacances avec une per­sonne touchée par cette mal­adie et sans avoir accès à Inter­net j’ai vite réal­isé qu’il me fal­lait une appli­ca­tion con­tenant tout le script de ce mag­nifique flim : La Classe Améri­caine. Je savais qu’un fou avait déjà fait tout le sale boulot et qu’il ne me restait plus qu’à extraire ces don­nées et créer l’interface pour les parcourir…

Grâce à Google Chrome et ses Out­ils de développe­ment j’ai pu injecter MooTools dans la page. Petite astuce très sim­ple et très pra­tique (script à copier/coller dans la console) :

  1. var scriptNode = document.createElement('SCRIPT');
  2. scriptNode.type = 'text/javascript';
  3. scriptNode.src = 'https://ajax.googleapis.com/ajax/libs/mootools/1.3.2/mootools-yui-compressed.js';
  4. var headNode = document.getElementsByTagName('HEAD');
  5. if (headNode[0] != null) headNode[0].appendChild(scriptNode);

Après ça, quelques lignes pour extraire les don­nées, les net­toyer et les stocker directe­ment dans le presse-papier au for­mat JSON :

  1. var data=[];
  2. var images=$$('table.script img');
  3. for (var i=0; i<images.length; i++) {
  4. var tr=images[i].getParent().getParent();
  5. var o={};
  6. var scriptTag=tr.getElements('td')[2];
  7. scriptTag.getElements('a').dispose();
  8. data.push({
  9. ts:tr.getElement('small').get('text'),
  10. script:scriptTag.get('html')
  11. .split('’').join("'")
  12. .replace(/\n/, '')
  13. .replace(/<br>\n$/, '')
  14. });
  15. }
  16. console.log(data.length);
  17. copy(JSON.encode(data));

Un petit coup de Flash Builder, saupoudré de Robot­legs et hop, une appli Android ! Pas de ver­sion iPhone pour l’instant, mais si quelqu’on m’offre de quoi me payer un cer­ti­fi­cat de développeur, je ne dis pas non !

Au revoir, Messieurs-Dames. C’est ça, la puis­sance intel­lectuelle. Bac + 2, les enfants.

Okr – Story of a failure

Some projects become real, oth­ers never see the light of day. This one is more of an abortion.

Six month ago I’ve been con­tacted by an archi­tec­tural firm to pro­vide some con­sult­ing on a project of theirs (I’m not going to name names, you’ll under­stand why). The goal was to find ideas to make a building’s front more inter­est­ing. The build­ing being a place to help and pro­mote Hip-Hop culture.

So I started work­ing on it and came up with ideas and con­cepts. The archi­tect I was in con­tact with seemed pretty happy with it and every­thing was look­ing good.

Until I no longer received any answer to my e-mails… Our last inter­ac­tion is now 5 month old and I think time has come to mourn. What I came up with can be inter­est­ing and since it involves an Open­Source project, here are a few bits about it.

At that time I was dis­cov­er­ing  GML (Graf­fiti Markup Lan­guage) and Evan Roth’s work. Bor­deaux hosted Les Grandes Tra­ver­sées and all of this really inspired me. So I thought of a mash-up between GML’s #000000book (black book, open archive of GML tags), a player of my own (Okr), the build­ing itself and Twit­ter. Here’s the doc­u­ment I pre­sented to explain what I had in mind.

The steps are:

  1. Cre­at­ing and send­ing a graffiti;
  2. Receiv­ing data;
  3. Con­vert­ing it to an image;
  4. Pro­ject­ing it on the building’s front;
  5. Photo-shooting of the front;
  6. Send­ing to Twitter;
  7. Online con­sul­ta­tion.

After a few e-mails with Jamie Wilkin­son (heads up!) I started work­ing on the core classes writ­ing GMLPlayer and GML­Cre­ator. The goal was to pro­vide both a way to dis­play tags and to create/upload them. I then built a UI around all that (a Flex one, after notic­ing Min­i­mal Comps didn’t work the way I expected).

iframe: <a href="http://toki-woki.net/p/Okr/">http://toki-woki.net/p/Okr/</a>

Note: you’ll also find the app on its ded­i­cated page. Try search­ing for “dasp” or “hello world” for exam­ple and play with the set­tings (the 3 top sliders).

Unfor­tu­nately it is only after cre­at­ing all this that I real­ized the project would never become real… So I sim­ply stopped work­ing on it. I am well aware that some parts of the code is a bit raw and could be opti­mized and I haven’t built the creation/upload fea­ture into the UI yet. Don’t know if I will, but the project is Open­Source so feel free to give it a spin! I also share my ini­tial attempt and a pixel ver­sion in case you’re interested.

Pretty happy that — even if not fea­ture com­plete — Okr made it to the GML project gallery, yay!

And just because a project will never see the light of day doesn’t mean it doesn’t need a proper logo, right?

AIR Application Updater: switch to the 2.5 namespace

I just wasted a few hours on under­stand­ing how to update an AIR app from the 2.0 name­space (or ear­lier) to the brand new 2.5 one. As you may know, two new tags have been intro­duced (“ver­sion­Num­ber” and “ver­sion­La­bel”) to replace the old “ver­sion” one.

To avoid break­ing things you have to cre­ate an inter­me­di­ary app ver­sion that will smoothly switch from 2.0 to 2.5, here’s what you can read on the release notes page:

In order to be able to update from ver­sion 1 to ver­sion 2, an inter­me­di­ary update step must be added as fol­lows: appli­ca­tion ver­sion 1, pack­aged with AIR 2 and using the 2.0 name­space gets updated to: appli­ca­tion ver­sion 1.5, pack­aged with AIR 2.5 and using the 2.0 name­space. This ver­sion of the appli­ca­tion must include the ver­sion of the Appli­ca­tion Updater SWC/SWF included with the AIR 2.5 SDK. This gets updated to: appli­ca­tion ver­sion 2.0, pack­aged with AIR 2.5 and using the 2.5 namespace.

Where “appli­ca­tion 1.5″ is the inter­me­di­ary step.

All of this looks quite sim­ple but really it isn’t; or at least it wasn’t for me. To be really explicit here are my 3 appli­ca­tion descrip­tors and the update descrip­tor (ver­sion num­bers changed to match Adobe’s example).

Appli­ca­tion descrip­tor – Ver­sion 1 (pack­aged with AIR 2.0):

  1. <?xml version="1.0" encoding="utf-8" standalone="no" ?>
  2. <application xmlns="http://ns.adobe.com/air/application/2.0">
  3. (...)<version>1</version>(...)
  4. </application>

Appli­ca­tion descrip­tor – Ver­sion 1.5 (pack­aged with AIR 2.5):

  1. <?xml version="1.0" encoding="utf-8" standalone="no" ?>
  2. <application xmlns="http://ns.adobe.com/air/application/2.0">
  3. (...)<version>1.5</version>(...)
  4. </application>

Appli­ca­tion descrip­tor – Ver­sion 2 (pack­aged with AIR 2.5):

  1. <?xml version="1.0" encoding="utf-8" standalone="no" ?>
  2. <update xmlns="http://ns.adobe.com/air/framework/update/description/2.5">
  3. (...)<versionNumber>2</versionNumber>(...)
  4. </update>

Update descrip­tor (PHP script receiv­ing the caller’s cur­rent ver­sion as “cur­rentVer­sion” GET variable):

  1. <?php
  2. header("Content-Type: text/xml; charset=utf-8");
  3. echo '<?xml version="1.0" encoding="utf-8"?>';
  4. $currentVersion=array_key_exists('currentVersion', $_GET) ? (float)$_GET['currentVersion'] : 1;
  5. $isNewNamespace=$currentVersion>=2;
  6. $ns='http://ns.adobe.com/air/framework/update/description/'.($isNewNamespace ? '2.5' : '1.0');
  7. $version=$currentVersion>=1.5 ? 2 : 1.5;
  8. $versionTag=$isNewNamespace ? 'versionNumber' : 'version';
  9. ?>
  10. <update xmlns="<?php echo $ns ?>">
  11. <<?php echo $versionTag ?>><?php echo $version ?></<?php echo $versionTag ?>>
  12. <url>http://www.your-site.com/update/your-app-<?php echo $version ?>.air</url>
  13. </update>

Not that sim­ple, right? And this is not only annoy­ing to the devel­oper, but also to the end user. He will be noti­fied of an update from ver­sion 1 to 1.5 and when he’s done he’ll get prompted about the new-new ver­sion (2): bang, another update process.

If you’re curi­ous of how I send the app’s ver­sion to the update descrip­tor, here it is:

  1. _appUpdater.updateURL='http://www.your-site.com/update/version.php?currentVersion='+App.getVersion();

The App class is avail­able in my as3bits repository.

Some help­ful links on the subject:

I hope this helps!

Evnt — Custom AS3 Event File Generator

I recently started work­ing with Robot­legs on a daily basis and I’ve never had to write that much cus­tom event classes, so I felt like it was start­ing to be a lit­tle bit bor­ing… That’s why I wrote a pretty basic/simple app that does hard part for you!

Sim­ply enter you cus­tom event’s class name and pack­age, drop in some con­stants and prop­er­ties: you’re all set!

Pro-tips:

  1. Reorder the con­stants and prop­er­ties by drag­ging and drop­ping them
  2. Use cus­tom types for the prop­er­ties, imports will be taken care of for you
  3. Hit “Copy to Clip­board” or “Save As…” for a quick export!

Project is brand new so it might require some fixes or improve­ments… If you have ideas, please share!

And before you ask: no, it wasn’t writ­ten with Robot­legs… But it’s Open­Source so if you want to take a spin and write the RL ver­sion of it, you’ll be able to do so!

Hope this helps!

Dok — AS3 Doc. UI

Meet Dok, my lat­est and nicest AIR app to this day!

Always look­ing for help when writ­ing AS3 for Flash, Flex and AIR? Think Adobe’s ref­er­ence is rich but brows­ing it sucks? Well, I did too. So I wrote this lit­tle thingy that loads, parses and caches help pages and then presents them in a slick and quick UI!

Since this app is only intended for devs and there­fore may not be very inter­est­ing to oth­ers, I decided it should look good. So I tried my best and worked hard on those pix­els and styles (col­ors and tex­tures inspired by that sweet clock)… Jump to the project page for life-size screenshot!

This project is absolutely Open­Source, from top to bot­tom. AS3 classes, MXML, Illus­tra­tor and Pho­to­shop files, PNGs and so on… Help your­self.

Flash+iPhone!

Quick news, good news. Devel­op­ing for the Apple iPhone using Flash is now pos­si­ble, hell! Read more here and there.

Expect me to build stuff with it!

Kwot

A new project is online! It’s called Kwot, and it allows you to share and store your favorite quotes.

The UI is quite min­i­mal­is­tic, with focus on sim­plic­ity. Nav­i­gate through quotes with your mouse wheel, your keyboard’s left and right arrow or the mini time­line at the bot­tom. Add a quote by click­ing on the plus but­ton at the bot­tom right hand cor­ner. If you don’t pick any color they’ll be auto­mat­i­cally cho­sen via a magic algo­rithm! Another magic algo­rithm will rotate your quote in 3D space. But don’t worry you will pre­view that in real-time, ha!

I might add user (login) sup­port, lan­guage tag­ging, an RSS feed and stuff like that but don’t expect that too soon, hol­i­days are coming!

If you don’t have the Flash plu­gin or if you visit the site on an iPhone the site will look quite dif­fer­ent but every­thing will remain!

A few things I used in case you won­der: swfad­dress (you will love deep-linking!), GTween, FlashDe­velop, AMFPHP, the view­port width attribute… Oh, and by the way, the font face is called Neu­tra.

Add some quotes and drop feedback!

eduMedia ’08

We have just updated our site!

We’ve been work­ing on this new ver­sion for about 9 months and now it’s here. The URL hasn’t changed, but the site has!

Let me show you what’s new…

Before/After

The site used to be designed for 800×600 screens, it is now for 1024×[anything], so the UI is wider and not as high as it used to be.

First thing you can notice: the blocks hold­ing the thumb­nails have been through a diet! Many UI ele­ments have been removed for cleaner and sim­pler nav­i­ga­tion. Here’s a quick comparison:

All of the but­tons have been removed but the func­tion­al­i­ties are still here, they’ve just moved to a more log­i­cal place. Also, the cross that indi­cated that you where not logged and had only par­tial access to the sim­u­la­tion is not here any­more. This lim­i­ta­tion is now shown with semi-transparency of the thumb­nail and its holder (not present in this screenshot).

The login form (at the top of every page) is now hid­den and acces­si­ble via a click on the “Log in” link. No extra click, though: your cur­sor will jump in the field automatically.

You now have a direct access to our tree at the bot­tom left of the home­page, faster! You can also search, with suggestions!

We worked on icons to illus­trate the header’s menu items.

On to the browse page!

Not much to say here, sim­pler, clearer, nicer. The RSS feed is clearly shown and you can sub­scribe to our newslet­ter, this is new!

We used to have a 3×3 grid of thumb­nails, we now have a 5×2 one. That’s less pages to browse in some cases!

The media page

It used to be a popup… Nasty. We all decided to avoid it and go for a reg­u­lar page.

The big new thing here are the price but­tons. We used to be quite shy about our com­mer­cial activ­ity. We now fully admit it, which is a good thing!

You can notice the “age bar”, allow­ing you to know who the sim­u­la­tion is intended for. Another new thing is the sug­gestor: sim­ply click on it and you’ll be sug­gested sim­i­lar simulations.

Again, icons. In the tool box:

Every other page has changed, but I’ll let you go and see that on your own! The biggest reworks have been the sub­scrip­tion or the “about us”, if you’re interested.

Our sim­u­la­tions

Not only did we change the UI of the site, we also redesigned our simulations!

Switch­ing from a dual color theme (blue for light sim­u­la­tions, orange for dark ones) to a sin­gle an more uni­ver­sal gray one. Every com­po­nent has been rethinked, here’s what what they look like:

A tech­ni­cal point of view

Of course to end up with this UI and func­tion­al­i­ties, you need some lines of code. Here’s what lies behind the site you see when browsing:

  • PHP5: my favorite back end lan­guage, in its last sta­ble version,
  • Post­greSQL: I’ve always pre­ferred it to its more famous friend MySQL,
  • CSS, lots of them. With Eric Meyer’s reset,
  • JavaScript, based on the nicest lib: MooTools (for Ajax and visual effects),
  • swfob­ject, to embed Flash files the right way,
  • TwinHelix’s PNG fix. Because we love 24 bits trans­parency but some browsers don’t.
  • A pimped out ver­sion of the PHP Lay­ers Menu Sys­tem, for the tree,
  • AMFPHP, for Flash remot­ing in PHP,
  • Action­Script 3 and Flash, to make things move!

And to write those lines of code, you’d bet­ter have good tools! Here’s what we used:

Of course we also used Illus­tra­tor and Pho­to­shop, for the graphics.

Clap, clap!

Heads up to the team, I think (and hope) we did a great job!

As always, if you’ve got feed­back please drop it there or on the site’s ded­i­cated page. We love feedback.

FFFFOUND AS3 API

I recently released FFFFOUND Desk­top, this AIR app uses a home-made API that I’m open sourc­ing today. The code is hosted on Google Code and is avail­able via SVN, I also uploaded a zip archive if you prefer.

You’ll find the (asdocs) docs in the repos­i­tory and in the archive.

By the way, I love feed­back. If you use it: please share!

Also, if you need exam­ples on how to use it, ask. I think the sources are self-explanatory but I might be wrong.

A few impor­tant things (also posted on the project’s page):

  • For now, this API will only work in AIR projects because ffffound.com’s crossdomain.xml is too restric­tive. I’ve con­tacted them but at this time they don’t want to change it.
  • The API relies on FFFFOUND’s RSS feeds but also on the site’s pages’ HTML, so some func­tion­al­i­ties might break at any time with­out warn­ing. Use with caution.

Watch the com­ments for any update or news!