google纪念玛莎·葛兰姆的logo,一大早就听群里面讨论,也许这个logo创意不错,得到大家的热捧。晚上抽空研究了下google的实现方法,此次的logo利用css的背景图定位+js实现。
自己找了个gif图改成css sprite背景图,做了个演示:查看
google的那个logo动画:查看
css、js部分其实不难,不过话说google攻城师的水平真不错。难点是把原始动画制作成CSS Sprites的部分,要规划好:如何才能用最小的图实现这个动画,如果仅仅单纯把动画里每帧的图铺起来,那意义就不是很大了。下面是注释过的js部分:
(function() { var K = { get:function(I){ return document.getElementById(I); }, create:function(T){ return document.createElement(T); }, remove:function(E){ return E && E.parentNode && E.parentNode.removeChild(E); }, on:function(E, N, FN){ E.addEventListener ? E.addEventListener(N, FN, !1) : E.attachEvent("on" + N, FN); } }, //把每个div的left、top、width、height信息存在js数组里 coords = [ [1, 6, 70, 74], [10, 4, 70, 76], [10, 4, 69, 76], [9, 4, 69, 76], [8, 4, 70, 76], [8, 5, 69, 75], [8, 6, 68, 74], [7, 6, 69, 74], [6, 7, 69, 73],[6, 6, 69, 74, 1], // 这里多了个值,表示下面开始调用背景图的下一行了 [5, 6, 69, 74], [4, 6, 70, 74], [4, 6, 70, 74], [3, 6, 70, 74], [2, 6, 70, 74], [1, 6, 70, 73], [1, 6, 70, 74], [1, 6, 70, 74], [1, 7, 70, 73], [1, 7, 70, 73, 1], [1, 6, 70, 74], [1, 6, 70, 74], [1, 7, 70, 74], [1, 7, 70, 74], [1, 6, 70, 74], [1, 6, 70, 74], [1, 6, 70, 74], [1, 6, 70, 74], [1, 6, 70, 74], [1, 6, 70, 74, 1], [1, 6, 70, 74], [1, 6, 70, 74], [1, 6, 70, 74] ], length = coords.length, num, repeatX, repeatY, rowHeight, timer = -1, logoId = K.get("hplogo"), nav = function() { alert("跳转页面"); }, draw = function() { var arr = coords[num]; if ( logoId && arr[0]) { var b = K.create("p"); b.id = "hplogo" + num; b.style.left = arr[0] + "px"; b.style.top = arr[1] + "px"; b.style.width = arr[2] + "px"; b.style.height = arr[3] + "px"; b.style.backgroundPosition = - repeatX + "px " + - repeatY + "px"; b.onmousedown = nav; //for IE、opera 点击涂鸦跳转 arr[3] > rowHeight && ( rowHeight = arr[3]); //记录当前背景片段所在行的高度(sprite图片中) //如果有arr[4],就表示开始调用背景图的下一行了,背景图的y坐标就需要 + 上一行的高度;背景x坐标当然要重置为0了, rowHeight当然也重置为0。 //如果没有arr[4],表示还在调用同一行的背景图,那么只需要增加x坐标的位置就OK了。 arr[4] ? ( repeatX = 0, repeatY += rowHeight, rowHeight = 0) : repeatX += arr[2]; logoId.appendChild(b); //本动画比google 动画简单,上一帧图像没有用途,所以直接隐藏掉了,google的那个这句就没必要了 num != 0 && (K.get("hplogo"+(num-1)).style.display="none"); ++ num; //num < length && ( timer = setTimeout( draw, 83)); //播放1次 timer = setTimeout( draw, 120); num === length && init(); //循环播放 } }, init = function() { //加载sprite图片完成,开始涂鸦 rowHeight = repeatY = repeatX = num = 0; //变量值初始化 //下面的代码起到循环播放的作用;只播放一次,可以删掉 timer != -1 && (clearTimeout( timer), timer = -1); for (var a = 0; a < length; ++a) {//如果已经添加了动画div,就移除 K.remove(K.get("hplogo" + a)) } draw(); // 开始涂鸦 }; //加载完成后才绘制动画 var bg = K.create("img"); K.on(bg,"load",init); bg.src = "sprite.png" })();
对比这个葛兰姆logo,我更喜欢“罗伯特·本生诞辰200周年”的logo,利用canvas、css、js。
verne,这个也还可以,支持css3的浏览器使用transform来做动画,不支持css3使用position来定位实现。
围观更多logo:http://www.google.com/logos/index.html