Skip to main content

Martha Graham's Google doodle is not a video, is an image (a CSS sprite)


Doodle

Today's Google doodle is featuring Martha Graham, an American modern dancer. The new doodle looks like a movie, but in fact it is only a CSS sprite.
The sprite is this one: 
Graham11-hp-sprite1
You may be wondering how is the animation/movie appearance achieved if it only uses this static image? 

The technique involves CSS sprites. A sprite is a composition of several images grouped together in order to reduce the number of required HTTP request to the server. This way a website with 50 images requires only one request for the large image composition. The entire doodle involves only one sprite, which speeds up loading a lot (compared to loading each frame separately). Google has used this technique to leverage data transfer from the servers and consequently make the animation load faster than a traditional video clip. 

So how is this sprite converted to an animation?

Pretend you are looking through pierced piece of paper, so that you can only look through the hole in the paper. Right behind the paper there is a film strip. If you move the film strip quickly from one side to the other you will think that there is actual motion happening. This is basically how movies are made.
Untitled-1
In CSS all you have to do is set the width and height of the container (the hole in the paper) and change the background-position at every frame. Google has done it using many div tags. 
The first div tag looks like this:
<div>&nbsp;</div> <pre><div id="hplogo0" style="left: 307px; top: 48px; width: 88px; height: 89px; background-image: url(http://www.google.com/logos/2011/graham11-hp-sprite.png); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial;  background-position: 0px 0px; background-repeat: no-repeat no-repeat;"> </div>
The second:
<div id="hplogo1" style="left: 307px; top: 48px; width: 89px; height: 89px; background-image: url(http://www.google.com/logos/2011/graham11-hp-sprite.png); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: -88px 0px; background-repeat: no-repeat no-repeat;"> </div>

Notice how the background position has been shifted, so that the next frame should look like this: 
Untitled-2
Changing the background position of the sprite very quickly therefore creates the illusion of animation.

Because Google tries hard to optimize the sizes of these doodles (that's why they did not simply create a video file) they have not even maintained equal ratios between the sample frames which would make it very simple to write a javascript function to move the background at each new frame (every 83 milliseconds). 

Therefore they are storing an array of coordinates where the next images should be positioned. I have copied their code and added a few comment to make it a bit more readable.
//This is the array of coordinates of each individual frame var d=[[307,48,88,89],[307,48,89,89],[307,48,91,89],[305,49,93,89],[305,50,93,88],[305,50,93,88],[306,52,92,86],[305,53,93,84],[305,54,94,83],[306,54,93,83],[307,54,92,83],[307,54,92,83],[308,54,90,83],[308,54,90,83],[306,53,91,84],[306,53,91,84],[308,53,90,84],[308,53,90,84],[305,53,92,84],[305,52,92,85],[306,52,91,85],[308,51,88,87,1],[308,50,88,88],[308,49,88,88],[307,49,89,88],[307,50,89,87],[308,51,89,86],[307,54,90,83],[307,57,90,80],[306,58,92,79],[306,58,92,79],[305,60,92,77],[302,61,95,76],[302,63,95,74],[302,51,96,86],[302,66,98,71],[304,67,96,69],[301,63,96,74],[301,58,93,79],[291,52,94,85],[288,50,71,88],[285,43,76,95],[285,37,70,101],[281,29,55,109],[278,20,58,119],[278,20,55,119,1],[277,12,121,127],[271,2,122,138],[267,1,126,139],[264,0,136,140],[260,0,141,140],[255,0,148,140],[252,0,151,140],[249,2,121,138],[247,3,123,137],[246,3,123,137],[246,2,124,137],[258,2,112,137],[263,2,106,137],[263,2,106,137],[262,2,103,137],[260,2,104,136],[260,2,104,137,1],[268,2,98,137],[267,2,99,137],[266,2,97,137],[266,3,96,136],[264,3,99,136],[263,3,100,136],[261,3,100,136],[259,2,138,137],[254,2,126,137],[247,2,101,136],[240,2,108,136],[238,1,110,137],[230,1,118,138],[220,15,128,124],[211,18,137,121],[205,43,102,96],[202,45,104,93],[200,38,97,101],[198,38,104,101,1],[197,39,107,100],[197,39,112,100],[213,39,94,110],[212,40,95,111],[211,41,97,111],[209,42,99,112],[209,43,98,112],[213,43,87,112],[213,42,83,113],[211,40,86,109],[211,38,86,103],[211,37,88,112],[211,20,186,131],[213,27,167,122],[212,44,87,105],[210,44,88,98],[195,44,106,98],[189,44,110,98],[182,46,117,99],[173,44,118,96,1],[161,43,130,99],[154,42,137,97],[153,42,137,97],[153,42,137,97],[152,41,137,98],[151,41,137,97],[149,41,145,97],[148,25,144,114],[148,13,144,126],[141,12,153,127],[115,11,173,128],[108,7,180,133],[108,4,180,136],[108,3,176,137,1],[108,1,161,139],[105,1,235,138],[103,1,295,148],[103,0,277,149],[108,0,234,137],[101,0,232,137],[99,0,135,139],[95,0,244,139],[81,0,152,139],[69,0,164,139,1],[66,0,169,139],[65,0,170,139],[63,0,168,138],[61,0,159,138],[35,0,304,139],[19,0,189,140],[18,11,138,129],[18,11,137,129],[18,11,137,128],[18,6,135,133],[7,4,146,136],[6,4,147,136],[3,4,150,136,1],[3,5,150,135],[3,8,150,132],[4,6,394,145],[12,6,388,145],[11,8,389,144],[11,8,387,144],[11,8,387,143,1],[10,8,113,131],[11,8,111,131],[10,9,112,130],[12,9,116,130],[12,9,111,130],[12,9,111,130],[12,9,110,131],[12,34,113,106],[13,35,110,104]],   //this function created all the DIV tags and adds them to the page every 83ms. (approximaterly 12 FPS) l=function(){ var a=d[f], c=document.getElementById("hplogo");  if(c&&a[0]){  var b=document.createElement("div"); b.id="hplogo"+f; b.style.left=a[0]+"px"; b.style.top=a[1]+"px"; b.style.width=a[2]+"px";b.style.height=a[3]+"px"; b.style.background="url(logos/2011/graham11-hp-sprite.png) no-repeat "+-g+"px "+-h+"px"; b.onmousedown=k; a[3]>i&&(i=a[3]); a[4]?(g=0,h+=i,i=0):g+=a[2]; c.appendChild(b); ++f; f< e && ( j=window.setTimeout(l,83) ) } }
I hope I have succeded to shine some light on how this Google doodle was made.





Comments

Popular posts from this blog

The Increased Addictiveness of Today's Video Games

This is a guest post by Miles Walker, a freelance writer and blogger who usually  compares car insurance  deals over at CarinsuranceComparison.Org. His most recent review looked at the best  car insurance quotes . Video games have always held some addiction, but now more than ever that addiction is growing. People are spending more time than ever playing the games, and game designers are constantly finding new ways keep it that way. Their efforts have a been a complete success, and some games have true addicts, addicts who play 24 hours a week or more. Visual enhancements Video games have come a long way since a certain duo of Italian plumbers started showing up in people's houses in the late 1980s. By leaps and bounds, video game graphics have become alarmingly sophisticated. Each graphical improvement increased a game's possibilities and added more depth to video games. Designers began thriving on this depth, making games with more achievements, unlocks, lev...

Basic cell counting and segmentation in Matlab

Counting cells manually is a tedious error prone process for humans. Given a large data set of microscopy images this task can be achieved much faster by means of basic computer vision techniques. In this tutorial we will segment cells from an image following a method similar to the one presented by Yongming Chen in 1999. The method uses basic morphological operations  and the watershed algorithm to segment the cells. Nowadays better methods for cell segmentation exist. This method was chosen for its simplicity and ease of implementation. We start with an image of cell-like structures by Anna-Katerina Hadjantonakis and Virginia E Papaioannou . A = imread('cells.jpg'); We convert the image to grayscale: I = rgb2gray(A); To be able to extract the dimmer cells, it is necessary to perform some local contrast adjustments I = adapthisteq(I); Objects on the borders can be caused by noise and other artifacts. We can eliminate objects on the borders...

How to differentiate between a Zeelander 44, 55 and 72?

One day, your life might depend on being able to tell the difference between a Zeelander 44, a 55 and the 72. At first glace, these boat models are quite similar to each other. You could easily think that a Z44 is a Z55 closer to you. Three different models. Which is which? To figure this out, you can spend 5 hours manually reviewing and annotating a thousands photos, deleting bad training data, and staring at tiny thumbnails photos of these boats until your eyes start bleeding. Then, put this data into a ResNet34, and see that after all of that effort you are able to tell each model from the others 60% of the time. In other words, it guesses correctly less than every two out of three attempts. A ResNet34 can tell these models from each other 60% of the time. That's crap. A waste of time and money. Here is how you differentiate these models like a human. The Z44 has windows in sets of two, the Z55 has windows in sets of three, the Z72 has an uneven window layou...