Google Doodle-Google首頁的javascript動畫初探


作者: | 2011/05/11 | 9 則迴響


今天早上除了發現自己過了10:42還活著之外,還發現Google首頁的Google Doodle有了新的動畫,今天的主題是瑪莎·葛蘭姆(Martha Graham)117歲誕辰 (不認識XD),不過這種手繪風格的動畫實在太有質感了,因此除了非常好奇的去看作者是哪位仁兄外,也想趁這個機會了解google是如何撰寫這個javascript動畫。

一開始當然是從習慣性的檢視原始碼開始,很快的發現了script標籤,接著把該段程式format整理一下排版,就成了給人看的javascript程式碼。大致觀察一下程式碼,很快的就會發現它將所有動畫圖片都放在一張大png裡(看起來有點大,但其實不過300多k的容量),將多張小圖放進一張大圖來存取,這是常見提升網站讀取速度的作法。

除了大圖之外,觀察程式碼可以很容易的發現在變數取名及程式碼描述上的用法都很精簡,像是變數取名 a,b,c,d,e,f,g…,還有到處可見三元表示式,以及使用 && 取代 if 敘述等的作法。

[javascript]
<style>
#hplogo
{
background:#020202;
height:156px;
position:relative;
width:403px
}
#hplogo div
{
pointer-events:none;
position:absolute
}
</style>

<div id=hplogo></div>
<script>
window.google={};
(function(){
try{
if(!google.doodle)
google.doodle={};

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]],
e=d.length,f,g,h,i,j=-1,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(http://commondatastorage.googleapis.com/blogimgs/graham11-hp-sprite.png) no-repeat "+-g+"px "+-h+"px";
b.style.border="1px solid #FF0000"; //加上border來觀察每張動畫的更新
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,183))}},m=function(){
google.doodle.a=!1;
i=h=g=f=0;
j!=-1&&(window.clearTimeout(j),j=-1);
for(var a=0;a< e;++a)
{
var c=document.getElementById("hplogo"+a);
c&&c.parentNode&&c.parentNode.removeChild(c)
}
j=window.setTimeout(l,183)
};
if(!google.doodle.a)
{
google.doodle.a=!0;
var n=document.createElement("img");
n.addEventListener?n.addEventListener("load",m,!1):n.attachEvent("onload",m);
n.src="http://commondatastorage.googleapis.com/blogimgs/graham11-hp-sprite.png"
}
}
catch(o){google.ml(o,!1,{cause:"DOODLE"})};
})();

</script>
[/javascript]
另外,因為好奇動畫的實際運作方式,所以做了一些修改來觀察:

  1. 把動畫速度調慢來觀察。
  2. 在產生圖片時加上紅邊框,所以可以發現它是一張一張取出後作成div,然後蓋在之前跑出來的動畫上。
  3. 把背景改成黑色,所以可發現png雖不是透明背景,但把它設為div的不重覆背景,也能巧妙的避開後面要留著的圖片。

最後,請見Demo比較原始版與修改版的不同


標籤:,

分類:,

本文作者是Audi Lu

9 則留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

*

*

*

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料