六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 127|回复: 0

编写基于Prototype的Javascript动画类

[复制链接]

升级  40%

4

主题

4

主题

4

主题

童生

Rank: 1

积分
20
 楼主| 发表于 2013-2-7 22:54:58 | 显示全部楼层 |阅读模式
<span style="border-collapse: separate; color: #000000; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; white-space: normal; font-size: medium;" class="Apple-style-span"><span style="color: #4b4b4b; font-family: Verdana,Geneva,Arial,Helvetica,sans-serif; font-size: 13px; line-height: 19px;" class="Apple-style-span">在AJAX如火如荼的今天,相信大家对Prototype这个Javascript类库应该都有所耳闻,它也的确使编写Javascript变得更简单。关于Prototype的文章,《Prototype简介》、《Prototype源码》诸如此类数不胜数;所以本文不会再做这几方面的介绍,并假设读者对Prototype有一定了解。
网页动画与原理

提到网页动画,大家首先想起应该Flash。不知道大家没有开发过Flash动画,故我想对此作一个简单的介绍(在我读大学的时候,对Flash也曾有过痴迷,所以也略懂一二)。Flash的动画主要分两类:渐变动画和逐帧动画。

  • 渐类动画——用户在时间轴上创建开始的关键帧和结束的关键帧,开发环境(Macromedia Profassional Flash 8等)会根据以上所创建的关键帧的颜色、位置和形状等,在计算出中间的过渡帧并添加到相应的时间轴上。这适用于创建简单的动画。
  • 逐帧动画——用户在时间轴的每帧上创建关键帧,并在其中绘制相应的图按。这适用于创建复杂的动画。
在Javascript中由于没有绘图API(应用程序接口),故只可以使用DOM+CSS改变元素的外观。而通过每隔一段时间调用一次改变元素外观的函数,实现类似Flash的渐类动画。
具体实现

因为不同的Javascript动画实现的基本原理都相同,所以可以创建一个基类将其抽象出来。代码如下:
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 1079px; background-color: #eeeeee;">var Animation = Class.create();
Animation.prototype 
= {
    
/*------------------------------------------------------------------------
     | 用途:
     |    构造函数
     |
     | 参数:
     |    element 将要实现动画效果的元素
     |    fps     每秒播放帧数
     ------------------------------------------------------------------------
*/    
    initialize: 
function(element, fps) {
        
this.element = $(element);
        
this.interval = Math.round(1000 / fps);
        
        
this.isPlaying = false;
        
this.currentFrame = 1;   
        
        
//创建一个用于存储中间状态的临时对象
        this.temp = { };             
    }
,
    
    
/*------------------------------------------------------------------------
     | 用途:
     |    子类覆盖该方法,实现自定义的动画补间
     ------------------------------------------------------------------------
*/    
    _createTweens: 
function(original, transformed, frames) { },
    
    
/*------------------------------------------------------------------------
     | 用途:
     |    创建动画补间
     |
     | 参数:
     |    original    开始状态
     |    transformed 结束状态
     |    frames      动画帧数
     ------------------------------------------------------------------------
*/    
    createTweens: 
function(original, transformed, frames) {
        
if(this.isPlaying) {
            
this.stop();
        }

        
        
this._createTweens(original, transformed, frames);
            
        
this.original = original;
        
this.transformed = transformed;
        
this.frames = frames;
        
        
//将开始状态拷贝到临时对象
        Object.extend(this.temp, original);        
    }
,
    
    
/*------------------------------------------------------------------------
     | 用途:
     |    判断临时对象状态是否超出结束状态
     |
     | 参数:
     |    prop 状态属性名称
     ------------------------------------------------------------------------
*/   
    _isOverstep: 
function(prop) {
        
if(this.original[prop] < this.transformed[prop]) {
            
return this.temp[prop] > this.transformed[prop];  
        }
 
        
return this.temp[prop] < this.transformed[prop];
    }

    
    _prepare: 
function() { },
    
    _draw: 
function(frame) { },
    
    _drawFrame: 
function() {
        
if(this.isPlaying) {
            
if(this.currentFrame < this.frames) {                
                
this._prepare();
                
this._draw(this.temp);
                
                
this.currentFrame ++;
            }
 else {
                
//最后一帧绘制结束状态            
                this._draw(this.transformed);
                
this.stop();
            }

        }

    }
,
    
    _play: 
function() { },
    
    play: 
function() {
        
if(!this.isPlaying) {
            
this._play();
            
            
this.isPlaying = true;
            
this.timer = setInterval(this._drawFrame.bind(this), this.interval);            
        }

    }
,
    
    _stop: 
function() { },
    
    stop: 
function() {
        
if(this.isPlaying) {
            
this._stop();
            
            
//回到开始状态
            this.isPlaying = false;
            
this.currentFrame = 1;
            
            Object.extend(
this.temp, this.original);
            clearInterval(
this.timer);
        }

    }
,
    
    _pause: 
function() { },
    
    pause: 
function() {
        
if(this.isPlaying) {      
            
this._pause();
                  
            
this.isPlaying = false;
            clearInterval(
this.timer);
        }

    }

}
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表