[转][javascript] Google谷歌首页点点效果

上周五抽空实现了一下谷歌首页(其实是韩国google先搞的)的动画效果,感觉挺有意思,在这里和大家分享下。

这个效果的思路蛮有趣的,是一个类似于我们小时候翻书动画(也叫走马灯?)的效果,将一张大的png图片每次显示一部分。

说明一下,我的实现没有google的那样精致,它最后还有一个返回一点的效果。我为了简单,省略了,呵呵。


首先,这是google用的素材图片:


这是我的素材图片:


区别就在于我把最后那条边裁了,就没有那一小点回退的效果了

然后是容器的css:

<style type="text/css">
        .animator_containter
{
            margin
: 0.5em auto; 
            background
: transparent url(ani.png) no-repeat scroll 0px 0px ; 
            width
: 52px;
/*每次显示部分png图片的宽度*/
            height: 37px; /*每次显示部分png图片的高度*/
            cursor: pointer; 
            -moz-background-clip
: -moz-initial; 
            -moz-background-origin
: -moz-initial; 
            -moz-background-inline-policy
: -moz-initial;
        
}

    
</style>

然后是namespace和常用方法:

/**
 * @author wjjin
 
*/



if (typeof(geekeesjs) == "#ff0000")
            _geekees 
= geekeesjs = {};

function $() {
    
var elements = new Array();
    
for (var i = 0; i < arguments.length; i++{
        
var element = arguments[i];
        
if (typeof element == 'string')
            element 
= document.getElementById(element);
        
if (arguments.length == 1)
            
return element;
        elements.push(element);
    }

    
return elements;
}

接着是一个Timer的类,用来在oo的编程方式下管理setTimeout和setInterval,这个类真的很实用,是偶尔发现的,出处忘了,对作者说个不好意思。

//Updated 4/18/2003: Footprint decreased, minor code improvements.
//
Updated 5/3/2003: Minor comment clarification; no code changes.
//
Updated 5/10/2003: Minor code improvements.
//
 The constructor should be called with
//
 the parent object (optional, defaults to window).

function Timer(){
    
this.obj = (arguments.length)?arguments[0]:window;
    
return this;
}


// The set functions should be called with:
//
 - The name of the object method (as a string) (required)
//
 - The millisecond delay (required)
//
 - Any number of extra arguments, which will all be
//
 passed to the method when it is evaluated.

Timer.prototype.setInterval 
= function(func, msec){
    
var i = Timer.getNew();
    
var t = Timer.buildCall(this.obj, i, arguments);
    Timer.set[i].timer 
= window.setInterval(t,msec);
    
return i;
    }

    Timer.prototype.setTimeout 
= function(func, msec){
    
var i = Timer.getNew();
    Timer.buildCall(
this.obj, i, arguments);
    Timer.set[i].timer 
= window.setTimeout("Timer.callOnce("+i+");",msec);
    
return i;
}


// The clear functions should be called with
//
 the return value from the equivalent set function.

Timer.prototype.clearInterval 
= function(i){
    
if(!Timer.set[i]) return;
    window.clearInterval(Timer.set[i].timer);
    Timer.set[i] 
= null;
    }

    Timer.prototype.clearTimeout 
= function(i){
    
if(!Timer.set[i]) return;
    window.clearTimeout(Timer.set[i].timer);
    Timer.set[i] 
= null;
}


// Private data

Timer.set 
= new Array();
Timer.buildCall 
= function(obj, i, args){
    
var t = "";
    Timer.set[i] 
= new Array();
    
if(obj != window){
        Timer.set[i].obj 
= obj;
        t 
= "Timer.set["+i+"].obj.";
    }

    t 
+= args[0]+"(";
    
if(args.length > 2){
        Timer.set[i][
0= args[2];
        t 
+= "Timer.set["+i+"][0]";
        
for(var j=1; (j+2)<args.length; j++){
            Timer.set[i][j] 
= args[j+2];
            t 
+= ", Timer.set["+i+"]["+j+"]";
        }

    }

    t 
+= ");";
    Timer.set[i].call 
= t;
    
return t;
}


Timer.callOnce 
= function(i){
    
if(!Timer.set[i]) return;
    eval(Timer.set[i].call);
    Timer.set[i] 
= null;
}

Timer.getNew 
= function(){
    
var i = 0;
    
while(Timer.set[i]) i++;
    
return i;
}


准备工作做完,接下来开始代码主题了,其实还是挺简单的,递归调用而已,只不过是oo的方法实现,看起来比较那个,呵呵。注释是用英文写的,看懂应该问题不大。

<script type="text/javascript">
        
//***************************Class _geekees.Animator********************************
        
        
//initialize
        if (typeof(_geekees.Animator) == "#ff0000")
            _geekees.Animator 
= {};
        
else
            alert(
"Animator is already set!");
    
        
//constructor
        _geekees.Animator = function( containerId
                                        , width
                                        , height
                                        , initialPosX
                                        , initialPosY
                                        , motionTime
                                        , stepX
                                        , stepY )
{
                    
            
this.container = $( containerId );
            
this.container.style.width = width + "px";
            
this.container.style.height = height + "px";
            
this.container.style.backgroundPosition = initialPosX + "px " + initialPosY + "px";
            
this.startPosX = 0;
            
this.startPosY = 0;
            
this.endPosX = 0;
            
this.endPosY = 0;
            
this.isForwardX = true;
            
this.isForwardY = true;
            
this.motionTime = motionTime;
            
this.timer = new Timer( this );//initial the Timer class
            this.stepX = stepX;//each time moving step
            this.stepY = stepY;
        }

        
        
//move method
        _geekees.Animator.prototype.move = function(){
            
            
if (this.isForwardX) {
                
if (this.startPosX < this.endPosX) {
                    
this.timer.setTimeout('move'this.motionTime);
                    
this.startPosX += this.stepX;
                }

            }

            
else {
                
if (this.startPosX > this.endPosX) {
                    
this.timer.setTimeout('move'this.motionTime);
                    
this.startPosX -= this.stepX;
                }

            }

            
            
if (this.isForwardY) {
                
if (this.startPosY < this.endPosY) {
                    
this.timer.setTimeout('move'this.motionTime);
                    
this.startPosY += this.stepY;
                }

            }

            
else {
                
if (this.startPosY > this.endPosY) {
                    
this.timer.setTimeout('move'this.motionTime);
                    
this.startPosY -= this.stepY;
                }

            }

            
            
//set the container status
            this.container.style.backgroundPosition = this.startPosX + "px " + this.startPosY + "px";
            
        }

        
        
//the method which to be called
        _geekees.Animator.prototype.animate = function( startX, endX, startY, endY ){
            
this.startPosX = startX;
            
this.endPosX = endX;
            
this.startPosY = startY;
            
this.endPosY = endY;
            
            
this.isForwardX = startX <= endX;//determine whether start position is larger than end position
            this.isForwardY = startY <= endY;
                        
            
this.move();
        }

        
//***************************End of Class _geekees.Animator********************************
        
        
        
        
        
/******************test*******************/
        
function go(){
            ani.animate( 
0-2080,  0 );
        }

        
        
function back(){
            ani.animate( 
-2080,  0,  0 );
        }

        
        
var ani = new _geekees.Animator( 'divAni'523700,  100 ,520);
    
</script>

最后是那个container,也就是一个div:
<div id="divAni" class="animator_containter" onmouseover="go();return false;" onmouseout="back();return false;">
        
</div>

完整代码下载
https://files.cnblogs.com/jinweijie/google_toolbar_ani.rar

【updated】
多个动画同时显示的调用
https://files.cnblogs.com/jinweijie/g_toolbar_multi.rar
posted @ 2008-06-04 02:12  眼里进了砂  阅读(341)  评论(0编辑  收藏  举报