Hakim

Experiments

This is my creative lab and interactive playground. It's focused on exploring interaction, visual effects and technologies. Right now, my experiments are primarily built in HTML but that is likely to change down the line.

Please don't use this as HTML vs Flash firewood. I do it because it's fun. Not because it's HTML.

Latest Tweets

Recap 2011

It's that time of the year again! In late 2010, having spent five great years working at Fi, I was determined to change up my professional life. After interviewing with Qwiki and accepting the position of Lead Interactive Developer it was decided; I was moving to San Francisco! It took a good few months of hard work to sort out all of the practicalities but it was definitely worth it now that I'm here.

Fortunately I've still been able to keep this site updated and worked on a variety of projects and experiments throughout the year.

The first project to see the light of day was Sketch, a drawing tool that mimics the style of old cartoons. It was refreshing to build something that allows others to be creative. Now – almost a year later – over 78,000 sketches have been saved.

Sketch was followed by a short freelance project which involved building an interactive and animated logo for a Canadian media production company called Meru. Try it out on their site; http://meru.ca/.

Next I stumbled into the land of CSS3 3D transforms and ended up trying them out on two projects; Holobox and CSS3 3D Slideshow (later renamed reveal.js). A few weeks ago, in mid December, I resumed my CSS 3D pursuits by creating a rolling effect for links and building a Christmas tree out of form elements.

Being far from tired of working with <canvas> I also created a new game called Coil, it's similar in design to Sinuous but adds a touch of WebGL and perhaps an element of stress to the gameplay. Shortly thereafter I worked on a tool called Textify.it which allows you to recreate images using thousands of letters of text. Using Phonegap, I was able to easily port Textify.it to iOS.

It's been really encouraging to see that there's still a lot of activity on sinuousgame.com even though it's been out since 2010 – meaning ancient, in internet-time. In the past year it saw more than 2,000,000 visits.

Now the new year is approaching and with it new adventures. 2012 will start with relocating to NYC and opening up Qwiki's new office. Can't wait to see where it goes from there!

DOM Tree

Origami

Happy holidays! I didn't get a pine tree for Christmas this year so I decided to compensate by creating a digital counterpart out of HTML form elements.

The DOM tree is generated via JavaScript every time you visit the page so you'll never see the same one twice. All of the forms are filled with holiday greetings in a variety of languages. CSS3 3D transforms are used to position and rotate, via translate3d() and rotate3d() respectively, the elements when the page loads. The infinitely looping rotation on the tree is controlled by an infinitely looping CSS3 animation.

All of the form inputs are interactive so I challenge you to try and select some of those <input type="radio"> snow flakes!

zoom.js

zoom.js is a small proof of concept JavaScript library for zooming in on DOM elements or points in a document. It uses CSS3 transitions and 2D transforms (scaling, translation, transform origin) on the <body> element to achieve animated magnification.

The API is very minimal;

zoom.in({ 
  element: <HTMLElement>
});

zoom.in({ 
  x: 150,
  y: 50,
  width: 300,
  height: 300
});

zoom.out();

reveal.js

reveal.js

Reveal.js, formerly CSS 3D Slideshow, is a tool which allows you to quickly create good looking HTML presentations. Beyond the changed name, the updated slideshow includes a fair amount of new features:

  • New and improved style.
  • Added controls in bottom right which indicate where you can navigate.
  • Reveal views in iteratively by giving them the .fragment class.
  • Code sample syntax highlighting thanks to highlight.js.
  • Transition themes (available via init options) default/concave/linear.
  • Initialization options (toggling controls, toggling rolling links, transition theme).

Sphere: Revisited

Sphere

The next js1k is still ways off but I felt like crunching some JavaScript so I revisited my Sphere experiment. I was able to squeeze it down into 309 bytes and that includes the code for creating and appending the <canvas> element to the body. Here's the full thing:

var a=document,b=a.body.appendChild(a.createElement("canvas")),c=b.getContext("2d"),d=0,e=b.width=a.width,f=b.height=a.height,g=Math.cos,h=Math.sin,j=Math.PI;setInterval(function(){b.width=b.width,d+=.1;for(i=1e4;i--;)r=(e+f)/2*(g((d+i)*(.05+.2*(h(d/1e5)/j)))/j),c.fillRect(h(i)*r+e/2,g(i)*r+f/2,1.5,1.5)},16)

Leave a comment if you can think of more ways to reduce the size!

UPDATE 1: Mathieu 'P01' Henri was able to squeeze it down to 247 bytes http://jsfiddle.net/LBBmM/1/

UPDATE 2: As if 247 wasn't enough, P01's latest update drops the canvas element and hits 222 bytes! http://jsfiddle.net/LBBmM/32/

Origami

Origami

Simply a colorful folding doodle on <canvas>. Click anywhere on the drawing -- or use your keyboard -- to activate different layouts.

404

Sphere

The folks over at .net magazine have decided to spruce up their 404 page with the help of a few guest artists. For my slot I decided to go for a creepy theme inspired by one of my earlier experiments. The animation is entirely code generated and drawn on an HTML5 canvas element.

If you're interested in how this was created, have a look at the source code on GitHub.

Sphere

Sphere

When bored, I sometimes open a blank JavaScript file and start writing without any clear objective of where I want to take it. This is the result of one such coding session.

The sphere -- actually more of a spiral -- is built out of 10,000 particles and the structure changes over time.

AppView

AppView

AppView was created to help iOS app developers track recent reviews in all markets of the App Store without having to use iTunes Connect's cumbersome UI. Reviews can be sorted on date, rating or store and are automatically translated to English via the Google Translate API.

Textify.it for iOS

Textify.it

I was really happy with how the Textify.it web app turned out and decided it was worthwhile creating a version targeted at iOS. I've been curious about the potential of building iOS apps using the standard array of open web technologies.

With the help of PhoneGap, a framework which bridges JavaScript to native functionality, it was incredibly easy to get going. The iOS version of Textify.it is based on the same JavaScript core as the online version. Some code was added to fire up the camera/library as well as for saving images onto the device.

One challenge with any HTML app targeted at iOS and Mobile Safari is rendering performance, particularly so when using the HTML5 canvas element. The mobile version of Textify.it maintains the original resolution of images and those images may well be 2048x1536 pixels large (iPhone 3GS). The most fruitful optimization for this was to use a CSS transform to scale the canvas rather than doing so via its width/height properties. This seems to force the browser to apply a different, faster, image scaling method. Jonas Wagner has written a post about a similar technique for improved performance here.

Textify.it is available for both iPhone and iPad with a $0.99 price tag.

Textify.it

Textify

Browser for or drag an image onto the page and watch it be reconstructed purely out of text. The markup for the resulting textual image can be copied and used elsewhere.

There are a lot of settings which allow you to control the characteristics of the text. Even the smallest tweak to the settings can result in a very different output. Beware that using very large amounts of text will cause heavy browser lag.

WebGL Particles

Particles

Was curious about how to efficiently render particles with WebGL so I built a tiny demo. Move your mouse to generate particles.

Canvas Optimization

Coil Debug Mode

Building Coil presented me with a few interesting technical challenges. Primarily I had a hard time making the game operate at a reasonable framerate since it uses both 2D Canvas and WebGL. Double whammy. Even though I am still not fully satisfied with how the game performs, I wanted to share some of the optimization techniques used.

Redraw Regions

The best canvas optimization technique for animations is to limit the amount of pixels that get cleared/painted on each frame. The easiest solution to implement is resetting the entire canvas element and drawing everything anew but that is an expensive operation for your browser to process.

To limit the areas which are cleared in Coil, I keep track of exactly which rectangular regions are being painted in so that I can then clearRect(x,y,w,h) only those. This results in the following flow:

1. Clear pixels of all redraw regions
2. Reset redraw region list
3. Paint all elements and store their individual redraw regions

Coil has a debug mode in which these redraw regions are displayed as green rectangles, try it out.

Procedural Sprites

Even though I'm an advocate for generating graphics procedurally, sometimes that's not the most efficient approach. If you're drawing simple shapes with solid fills then by all means drawing them procedurally is the way to go. But if you're drawing more detailed entities with strokes, gradient fills and other performance sensitive make-up you'd be better off using image sprites.

In Coil I use a hybrid approach. Graphical entities are generated procedurally on canvas, but only once as the game starts up. For the rest of the game's lifespan I paint copies of those sprites rather than repeatedly generate the same drop-shadow, gradient and strokes.

One final tip when working with image sprites is to always draw them on integer x/y coordinates for better performance on OS X browsers. You can read about this in greater detail here.

Computation Distribution

The Chrome Developer Tools profiler is very useful for finding out what your performance bottlenecks are. In my case, for Coil, the two heaviest operations were the discovery of enclosures and rendering of WebGL. Both of these operations were being executed on every frame.

To distribute the processing for these two operations I changed it so that enclosure discovery only occurs on even frames while WebGL only gets rendered on odd frames.

Performance Based Scoring

From a scoring point of view, bad performance can be beneficial when playing a reflex based game since it gives you more time to react. To combat this unfair advantage I scale down the scores by a factor of the current FPS divided by the target FPS.

Another, perhaps more elegant, solution to this problem is to base all game mechanics on time rather than frames.

Coil

Coil

While working on Sinuous I had an idea for a gameplay feature that involved drawing circles around your enemies to destroy them. Trying not to add too many features in one game I decided not to implement it at that point and instead revisit it as a separate game.

Much like Sinuous, Coil is a very straight forward game with as few features and gameplay elements as possible.

The objective is to defeat enemies by enclosing them in the trail formed by your tail. Enemies found within those closures are obliterated. There are two types of enemies; the blue kind explodes after time and causes you damage, red enemies on the other hand are obstacles which should never be drawn into the enclosed area as that will also cause you damage.

Determining how to isolate enclosed areas, and enemies therein, was a very interesting challenge. The final implementation is a three-step process. First I check all line segments in the tail for intersections with each other. Once an intersection is discovered, that enclosed area is filled with a unique color. Finally, collisions are found by checking if the color underneath an enemy matches the closure's unique fill color.

CSS3 3D Hologram

CSS 3D Hologram

After seeing a video demonstration of a holographic effect created with HTML/CSS I was inspired to build something similar. I ended up creating a 3D box which alters perspective depending on device orientation.

CSS3 3D transforms are used to distort HTML elements and create the walls of the box. JavaScript then tracks the deviceorientation and devicemotion events and updates the 3D perspective accordingly. The only property that is being changed via JavaScript is the perspective origin, or -webkit-perspective-origin to be exact.

Note that this requires a webkit browser and has only been tested on iPhone.

WebGL Shaders

Trail

WebGL's introduction is very exciting due to the powerful graphical capabilities it enables in the browser context. This power originates from the ability to run highly optimized programs on the GPU via shaders written in the OpenGL Shading Language – or GLSL for short.

There are two types of shaders; vertex shaders which are used to calculate transformations of vertices and fragment shaders which are used to process indiviual pixels.

Aiming to start learning more about the GLSL language I wrote a few abstract fragment shaders. To avoid some of the rudimentary work I used three.js to compile and run my shaders. I've also been referencing the wonderful Shader Toy for learning examples.

01 02 03

CSS3 3D Slideshow

CSS 3D Slideshow

While preparing a presentation on SVG for an upcoming Stockholm Web Monkeys meetup I needed to construct a simple slideshow. Since this would only ever be presented in a controlled environment, I decided to take the opportunity and experiment with CSS 3D transforms.

The transition between slides is made possible by a combination of CSS 3D transforms and transitions. JavaScript is in charge of updating the class names of all slides depending user input and CSS takes it from there. Thanks to the limited logic involved I was also able to avoid using any third party libraries.

Each slide can contain a nested slideshow. The top level slideshow is navigated via keyboard left/right and the nested slideshows are then reached by using the up/down arrows.

Tip: you can improve the rendering performance of transitions/animations in mobile Safari by applying a dummy CSS 3D transform. For example: -webkit-transform: translate3d(0,0,0).

Note that this requires a browser with support for CSS3 3D transforms, such as Chromium or mobile Safari.

02-08-2011: The slideshow now provides unique URL's per slide which in turn enables support for internal links.

BreakDOM

BreakDOM

Ever wondered what it would feel like to attack a bunch of checkboxes with a radio button that's being steered by a scrollbar?

This is a remix of the classic Breakout game except all game elements have been replaced with HTML user interface elements.

Meru Logo Animation

In early 2011 I collaborated with Canadian media production company Meru on a small but very interesting project. The objective was to "...produce a code generated logo that reacts to various inputs..." and works on all platforms. Having looked at the fluid shape in the logo design I felt this would be a lot of fun to take on – and so I did.

I animated the logo using the HTML <canvas> element and created a fallback with rotating images for sans <canvas> browsers. The animtion consists of a few core properties of the logo, such as shape and color, changing slowly using a fine combination of randomness and control. Realizing that it would take some value tweaking for everyone involved to be satisfied with the look and feel, I provided an easy way for Meru to configure the logo. If you're curious about how this looks you can view the source of this page and look for MeruLogo.initialize.

The animation also works with touch input and runs smoothly on most mobile devices. That latter part is somewhat of a surprise since everything I've done with <canvas> up till this point has always been dissapointingly slow in those environments. The primary reason for why it works so well in this case is that it's rendered at a relatively small resolution.

I'm really happy with how this turned out in the end. The organic nature of the animation compliments the logo design very well without sacrificing any of its core visual principles.

Spring Cleaning

Out with the old, in with the new! I finally got around to creating a new site for myself.

Even though it hadn't grown very old, my previous portfolio ended up being a limitation in what type of content I could publish so I decided it was time for a revamp.

I Joined the Qwiki team!

Project Image

Translating information from a format aimed at computers into a presentation tailored for human beings is an incredibly powerful concept. That is what Qwiki does. And does incredibly well. After first discovering the product late last year I couldn't stop playing around with it. Coincidentally I received an email a few weeks late from Doug Imbruce, founder and CEO of Qwiki, asking for a meeting. After that meeting – and many interviews – I was offered a job and accepted straight away.

Having worked many years in the advertisment industry I'm excited about the move to a product oriented environment. Mainly because I want to invest my time and effort in one product that I personally believe in. I also want to broaden my scope and what better way to do so than diving into the San Francisco startup scene.

Qwiki is truly a great company to be a part of. Everyone working there is genuinely talented at what they do and passionate about the future of the product. Besides that, the office is also ridiculously well equipped, including: catered breakfast/lunch/dinner every day, top of the line hardware, ping pong table, basketball hoop, beer tap, wine fridge and a turtle.

Want to join me in improving the way people experience information? Check out the job listings and benefits.

20 Things - Page Flip

Project Image

Following the launch of 20 Things I Learned About Browsers And The Web there was a lot of interest regarding some of the HTML5 techniques empowering the site. In particular, the page flip transition was a hot topic.

To explain how the page flip works, and how to create one of your own, I wrote a tutorial which was published in .net Magazine (issue #211). This tutorial later went on to be available on Google's HTML5Rocks.com as well.

Sketch

Sketch

Remember those old cartoons where hand drawn lines appeared to vibrate because of differences between frames? That's what this experiment simulates. It also adds a third dimension to your drawings by allowing you to rotate the canvas.

Sketch Gallery

Drawings can be saved and shared in the gallery.

Hakim El Hattab

I'm a web developer and creative programmer from Sweden that is as passionate about working with animation and interactivity as I am technical implementation. My work experience is broad and includes campaign sites in Flash, web apps in HTML, desktop apps in AIR, experimental HTML5 and CSS3 projects as well as mobile development. I used to work at Fi, a digital production agency in Stockholm, but recently moved to San Francisco to take on the role of Lead Interactive Developer at a well known startup; Qwiki.

During my time with Fi I lead the development of both small and large-scale projects for brands such as Google, BBC, Nintendo, Wacom and SAS.

My personal projects and experiments with HTML5, CSS3 and JavaScript have received a resounding amount appreciation and recognition. They have been served to over 4,000,000 people around the globe in the past year alone.

I am also an active part of the web development community and share the source code for most of my work on GitHub.

Here's a list of some selected projects that I've had the pleasure to work on:

Pool

Pool in WebGL

This is my first experiment with WebGL. Even though I am very much for the idea of using librares to abstract away some of the rudimentary work involved in programming, I believe it is crucial to understand what happens behind the curtains. With that reasoning in mind, I set off to create this very basic example only so that I would gain an understanding of what makes WebGL tick.

Interested in getting started with WebGL? I highly recommend going through The Lessons on learningwebgl.com.

HTML5 Canvas Tips

As the HTML5 spec is slowly making its way from working draft to recommendation and browser implementations are solidifying – the urge to make use of these new features grows strong.

Coming from a Flash background, and being a sucker for anything that moves or can be interacted with, I am most excited about the introduction of the <canvas> element which allows for bitmap drawing through JavaScript. I started creating some visual experiments using canvas a few months back and have gathered some tips for anyone dabbling in this neck of the woods.

Performance

When working with animation on canvas, performance can be a challenge since bitmap operations are very processing expensive, especially at high resolutions. One important optimization rule to follow is to reuse as many pixels as possible between frames. What I mean by that is the fewer pixels that need to be processed each frame, the faster your program will run. For example, when erasing pixels with the clearRect(x,y,w,h) method, it is very beneficial to clear and redraw only the pixels that have changed and not the full canvas. Unlike the Flash Player’s redraw regions, this management of “dirty rectangles” needs to be done manually for canvas.

State Stack & Transformation

The canvas can be manipulated via transformations such as rotation and scaling, resulting in a change to the canvas coordinate system. This is where it’s important to know about the state stack for which two methods are available: context.save() (pushes the current state to the stack) and context.restore() (reverts to the previous state). This enables you to apply transformation to a drawing and then restore back to the previous state to make sure the next shape is not affected by any earlier transformation. The states also include properties such as the fill and stroke colors.

Compositing

A very powerful tool at hand when working with canvas is compositing modes which, amongst other things, allow for masking and layering. As an example you can check out Bakemono, where composite modes are used to mask the eye and mouth. There's a wide array of available composite modes and they are all set through the canvas context's globalCompositeOperation property.

Anti-Aliasing

To allow for sub-pixel drawings, all browser implementations of canvas employ anti-aliasing (although this does not seem to be a requirement in the HTML5 spec). Anti-aliasing can be important to keep in mind if you want to draw crisp lines and notice the result looks blurred. To work around this you will need to either round to integer values or offset by half a pixel depending on if you’re drawing fills or strokes.

Clearing the Canvas

To clear the entire canvas of any existing pixels context.clearRect(x,y,w,h) is typically used – but there is another option available. Whenever the width/height of the canvas are set, even if they are set to the same value repeatedly, the canvas is reset. This is good to know when working with a dynamically sized canvas as you will notice drawings disappearing.

Next Steps

If you’re interested in learning more about canvas, I would suggest getting started by reading through Mark Pilgrim's wonderful Dive Into HTML5 chapter. Once you're up and going this cheat sheet is a great point of reference.

Conclusion

Canvas has been around for quite a while already and is supported by all modern, and some not so modern, browsers. This being the case, I think it’s very much ready to be used for real production. Some suitable places to utilize canvas would be to enrich buttons, charts/data visualization and navigational elements such as a list of thumbnails for an image gallery.

Sinuous on the Google Chrome Web Store

Sinuous analytics

Preceding the release of the Chrome Web Store (CWS) I collaborated with Google to prepare Sinuous as a launch title app. Following the launch in early December 2010, Sinuous saw a major increase in activity and players. In fact, sinuousgame.com has seen over 900,000 visits since its launch and traffic is now resting at about 5k visits/day.

There are two different ways to deploy apps on the CWS:

  1. Offline apps that are downloaded to the client.
  2. Online apps that open an existing app URL.

The latter has raised some discussion – and complaints – because it essentially means that the "app" is no more than a bookmark. In some ways I agree with this, but I still picked this route to avoid having to maintain and update separate versions of the game.

If my app is merely a link to the original game, why do I bother to use the CWS at all? One reason: exposure. The CWS is a very powerful promotional channel for finding an audience.

20 Things I Learned About Browsers and the Web / Fi

20 Things

An online book that aims to better people's understanding about the inner workings of browsers and the web. This project was created for the Google Chrome Team while I was working at Fi and my primary responsibility was building the HTML5 front end.

Collaborating with the Google Chrome team on this project was a great experience. The expertise they brought to the table, both in terms of technology but also in general project process and structure, was invaluable.

I'm really proud of the end result. It demonstrates a use of HTML5 that can not be found in many other applications and has therefore shed light on what can actually be accomplished using these technologies.

Created as part of a team while working at Fi.

Sinuous Won 10k Apart

Project Image

The 10k Apart competition, organized by MIX Online together with An Event Apart, challenged developers to build web apps in HTML5 using less than 10kb.

In the end 367 applications had been submitted and out of those my game, Sinuous, ended up taking home the grand prize!

BBC - Life Is... / Fi

Project Image

This site, built entirely in Flash, is used to showcase some of BBC Earth's stunning nature photography. It's centered around a fluid interface that blends organically into the edges of the page so that you can focus on what matters; the content.

Created as part of a team while working at Fi.

Sinuous

Sinuous

A game built on the HTMLCanvas element which will test your mouse pointer reflexes. The objective is to stay clear of the evil red dots and stay alive as long as possible. Even though the game play is linear sinusoidal and the graphics are minimalist it can get quite addictive.

Sinuous is the grand prize winner of the 10k Apart competition for best HTML application in under 10 kb and has seen close to one million plays to date. The game was also released, and featured on the Google Chrome Web Store.

Sinuous

Sinuous

A game built on the HTMLCanvas element which will test your mouse pointer reflexes. The objective is to stay clear of the evil red dots and stay alive as long as possible. Even though the game play is linear sinusoidal and the graphics are minimalist it can get quite addictive.

Sinuous is the grand prize winner of the 10k Apart competition for best HTML application in under 10 kb and has seen close to one million plays to date. The game was also released, and featured on the Google Chrome Web Store.

Bakemono

Bakemono

A little monster that I brought to life with JavaScript. Bakemono is Japanese for monster.

Keylight

Keylight

A playhead travels between keys which resonate in sound depending on where they are placed in the room.

Wave

Wave

A wave with bubbles floating on the surface, the bubbles each represent a tweet with the word "water" in it.

And then?

More Work

There's much more to put in here but as it turns out – it takes time to write up descriptions and collect old material. To be continued...