天天看點

Google首頁現代舞先驅瑪莎·葛蘭姆JS代碼分析(附源碼下載下傳)

  2011年5月11日,google為了紀念現代舞先驅瑪莎·葛蘭姆 117 周年誕辰,用巧妙的技術和奇特的創意在首頁建立了一副跳舞的圖,我把整個源碼下載下傳下來并加以分析和重構,效果圖如下:

Google首頁現代舞先驅瑪莎·葛蘭姆JS代碼分析(附源碼下載下傳)

整個動畫實際上是由155張小圖檔做出來的(google的設計師太nb了),就像放電影那樣,如下圖:

Google首頁現代舞先驅瑪莎·葛蘭姆JS代碼分析(附源碼下載下傳)

雖然原理很簡單,就是用js來控制播放上面的圖檔,不過裡面還有很多技巧是值得學習的,下面是我對代碼的分析。

html部分很簡單,就一個div容器:

<div id="hplogo"> 

    <a href="#"> 

        <img title="現代舞先驅瑪莎·葛蘭姆 117 周年誕辰" border="0" alt="現代舞先驅瑪莎·葛蘭姆 117 周年誕辰" src="images/graham11-hp-start.png" /> 

    </a> 

</div> 

css部分:

#hplogo { position: relative; cursor: pointer; width: 403px; height: 156px; margin: 120px auto 0 auto; background: #fff none repeat 0% 0% scroll; }  

#hplogo div { position: absolute; } 

js部分(完整代碼在附件中):

(function() {  

            try {  

                //二維數組定義155張圖檔的資訊,分别是[圖檔的left, top, width, height, 1(标記,部分數組有)]  

                //數組中最後一個值“1”是一個标記,表示圖檔換行  

                var arrimg = [[307, 48, 88, 89], [307, 48, 89, 89], [307, 48, 91, 89]...(省略n個數組)],  

                imglen = arrimg.length, //圖檔數組長度  

                imgindex, imgleft, imgtop, maxheight,   //分别代表 目前圖檔序号,background-position中的left, top,一行圖檔中的最大高度  

                fun = -1,   //後面settimeout的傳回值,做标記,後面用到  

                funimgclick = function() {  //點選圖檔的事件(跳轉到google搜尋頁面)  

                    google.nav && google.nav.go ?  

                    google.nav.go("/search?q=%e7%8e%9b%e8%8e%8e%c2%b7%e8%91%9b%e5%85%b0%e5%a7%86&ct=graham11-hp&oi=ddle&hl=zh-cn") :  

                    window.location.href = "/search?q=%e7%8e%9b%e8%8e%8e%c2%b7%e8%91%9b%e5%85%b0%e5%a7%86&ct=graham11-hp&oi=ddle&hl=zh-cn" 

                },  

                funmakeanimate = function() {   //建立并執行動畫的方法,每83毫秒調用一次,建立一個div并設定屬性、背景圖  

                    //取出目前圖檔資訊  

                    var img = arrimg[imgindex],  

                    //所有div都添加到這個容器  

                    wrap = document.getelementbyid("hplogo");  

                    if (wrap && img[0]) {  

                        //開始建立div  

                        var div = document.createelement("div");  

                        div.id = "hplogo" + imgindex;  

                        div.style.left = img[0] + "px";  

                        div.style.top = img[1] + "px";  

                        div.style.width = img[2] + "px";  

                        div.style.height = img[3] + "px";  

                        div.style.background = "url(images/graham11-hp-sprite.png) no-repeat " + -imgleft + "px " + -imgtop + "px";  

                        div.  

                        //這裡使用了利用&&運算符的技巧,下面還會用到這個技巧  

                        //相當于"if (img[3] > maxheight) { maxheight = img[3]; }"  

                        img[3] > maxheight && (maxheight = img[3]); //保證maxheight取目前行最大的圖檔高度  

                        //如果有5個值,則說明換行了,left重新從0開始,并累加top,行最大高度清0  

                        //否則left累加目前圖檔的寬度  

                        img[4] ? (imgleft = 0, imgtop += maxheight, maxheight = 0) : imgleft += img[2];  

                        wrap.appendchild(div);  

                        ++imgindex;  

                        //繼續動畫  

                        imgindex < imglen && (fun = window.settimeout(funmakeanimate, 83)); //又是 && ,同上  

                    }  

                funinit = function() {  //頁面加載的時候就執行該函數,初始化變量并調用動畫函數  

                    maxheight = imgtop = imgleft = imgindex = 0;  

                    //如果動畫已經在播放,則先停止并删掉相應的div節點  

                    //再次出現 && 的使用  

                    fun != -1 && (window.cleartimeout(fun), fun = -1);  

                    //删除已經添加的dom節點  

                    for (var index = 0; index < imglen; ++index) {  

                        var div = document.getelementbyid("hplogo" + index);  

                        div && div.parentnode && div.parentnode.removechild(div);  

                    //第一次調用動畫函數  

                    fun = window.settimeout(funmakeanimate, 83);  

                };  

                var originimg = document.createelement("img");  

                //頁面  

                originimg.addeventlistener ?  

                    originimg.addeventlistener("load", funinit, false) : //addeventlistener用于mozilla系列浏覽器,第三個參數usercapture若為true,則浏覽器采用capture,若為false則采用bubbing方式  

                    originimg.attachevent("onload", funinit);   //用于ie浏覽器  

                originimg.src = "images/graham11-hp-sprite.png";  

            }  

            catch (o) {  

                //google的錯誤處理  

                //google.ml(o, !1, { cause: "doodle" });  

        })() 

繼續閱讀