抖动效果

做的一个抖动效果,兼容IE6/7/8/FF/OPERA/SAFARI,先看效果:

抖抖更建康
喝前抖一抖
左抖右抖上抖下抖

抖动效果的原理主要是:将需要抖动的元素按上右下左移动。利用Math.sin和Math.cos计算x轴以及y轴的偏移,稍后会提到。

在这里,我首先定义了2个参数,也是在创建实例是可以修改的2个参数

this .options = {
    z:
3 // 抖动半径
    maxa: 1080   // 总计抖动角度 1080/360圈
}

然后是实例调用的3个方法,这3个方法分别是3种抖动的方式(上下,左右,上下左右),这里需要在调用时给函数传个抖动元素的ID。

PS:mode是抖动方式  "h"左右抖动;"v"上下抖动;"c"上下左右抖动。

h: function (objID){  // 左右抖动        
     this .oID  =  objID;
    
this .mode = " h " ;
    
this ._start();
    
},
v:
function (objID){  // 上下抖动
     this .oID  =  objID;
    
this .mode = " v " ;
    
this ._start();
},
c:
function (objID){  // 上右下左抖动
     this .oID  =  objID;
    
this .mode = " c " ;
    
this ._start();
}

定义好抖动元素ID和mode之后,我们就执行抖动操作。

_start: function (){
    
this ._end();
    
if ( this ._init()){
        
this .i  =  setInterval( this ._exe(), 30 );
    }
}

_end()是用来停止上个抖动操作,并还原上个抖动元素的位置。_init()是用来初始化抖动参数。我们把角度还原到0,然后获取对象的left和top。

_init: function (){
    
this .obj  =  document.getElementById( this .oID);
    
if ( this .obj){
        
this .a  =   0 // 角度
         this .os  =   this .obj.style;
        
this .oleft  =   this .os.left  ==   " auto "   ?   0  :  ~~ this .os.left;
        
this .otop  =   this .os.top  ==   " auto "   ?   0  :  ~~ this .os.top;
        
return   true ;
    }
else {
        
return   false ;
    }
}

初始化参数之后,我们就可以使用setInterval来移动我们的元素。我们都知道setInterval里的函数以及内部的this都是指向window的,为了解决这个问题,我这里用了闭包。

_exe: function (){
    
var  object = this ;
    
return   function (){
        
var  r  =  object.a  *  Math.PI  /   180  , x  =  Math.sin(r) * object.z , y  =  Math.cos(r) * object.z;
        
if (object.mode  ==   ' c '   ||  object.mode  ==   ' h ' ){
            object.os.left 
=  object.oleft  +  y  +   " px " ;
        }
        
if (object.mode  ==   ' c '   ||  object.mode  ==   ' v ' ){
            object.os.top 
=  object.otop  +  x  +   " px " ;
        }            
        
if ( (object.a += 90 >  object.maxa ){
            object._end();
        }
    }
}

上面我们已经谈到了,抖动的原理就是将元素上下左右画圆的偏移,如果只是需要将其偏移幅度设定为直角,那我们可以直接oleft+z otop+z来进行处理,但当我们将幅度设定为30° 45°的时候,显然就行不通了,这个时候我们就根据半径z来计算x和y了,我们的三角函数cos/sin就派上用场了(还记得这两个函数吗(^。^)y-~~)。通过sin计算x轴,通过cos计算y轴,这里需要注意的是,在javascript里,sin和cos里的参数不再是角度,而是弧度,将角度乘以 0.017453293 (2PI/360)即可转换为弧度。当我们的偏移角度超过我们设定的最大角度,我们即可停止抖动。

PS:参考http://www.w3school.com.cn/js/jsref_sin.asp

js基本原理就是这样,另外需要提醒的是,由于我的偏移使用的是left和top,所以抖动的元素必须增加position:relative||absolute||fixed,使用left而不是使用margin-left,个人感觉在做偏移上left效率更高,下面是完整代码:

ContractedBlock.gif ExpandedBlockStart.gif View Code

   
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=utf-8" />
< title > 无标题文档 </ title >
< script >
var extendJson = function (target,src){
for ( var json in src){
target[json]
= src[json];
}
return target;
}
var $class = function (constructor,prototype) {
var c = constructor || function (){};
var p = prototype || {};
return function () {
for ( var atr in p) {
arguments.callee.prototype[atr]
= p[atr];
}
c.apply(
this ,arguments);
}
}
var Shake = function (options){
options
= options || {};
this .options = {
z:
3 , // 抖动半径
maxa: 1080 // 总计抖动角度 1080/360圈
}
extendJson(
this .options,options);
this .z = this .options.z;
this .maxa = this .options.maxa;
this .mode = " c " ; // 抖动的模式 "h"左右抖动;"v"上下抖动;"c"上下左右抖动;

}
var proto = {
_setZ:
function (z){ this .z = z;},
_getZ:
function (){ return this .z;},
_setMaxa:
function (maxa){ this .maxa = maxa;},
_getMaxa:
function (){ return this .maxa;},
_init:
function (){
this .obj = document.getElementById( this .oID);
if ( this .obj){
this .a = 0 ; // 角度
this .os = this .obj.style;
this .oleft = this .os.left == " auto " ? 0 : ~~ this .os.left;
this .otop = this .os.top == " auto " ? 0 : ~~ this .os.top;
return true ;
}
else {
return false ;
}
},
_end:
function (){
if ( this .os){
clearInterval(
this .i);
this .os.left = this .oleft + " px " ;
this .os.top = this .otop + " px " ;
}
},
_exe:
function (){
var object = this ;
return function (){
var r = object.a * Math.PI / 180 , x = Math.sin(r) * object.z , y = Math.cos(r) * object.z;
if (object.mode == ' c ' || object.mode == ' h ' ){
object.os.left
= object.oleft + y + " px " ;
}
if (object.mode == ' c ' || object.mode == ' v ' ){
object.os.top
= object.otop + x + " px " ;
}
if ( (object.a += 90 ) > object.maxa ){
object._end();
}
}
},
_start:
function (){
this ._end();
if ( this ._init()){
this .i = setInterval( this ._exe(), 30 );
}
},
h:
function (objID){ // 左右抖动
this .oID = objID;
this .mode = " h " ;
this ._start();

},
v:
function (objID){ // 上下抖动
this .oID = objID;
this .mode = " v " ;
this ._start();
},
c:
function (objID){ // 上右下左抖动
this .oID = objID;
this .mode = " c " ;
this ._start();
}
}

var Shk = $class(Shake,proto);
var shk = new Shk({z: 10 });
</ script >
</ head >

< body >
< button onclick ="shk.v('shakeBox1');return false;" > 抖抖更建康 </ button >
< div id ="shakeBox1" style ="position:relative;" >
< input type ="text" />
</ div >
< button onclick ="shk.h('shakeBox2');return false;" > 喝前抖一抖 </ button >
< div id ="shakeBox2" style ="position:relative;" >
< input type ="text" />
</ div >
< button onclick ="shk.c('shakeBox3');return false;" > 左抖右抖上抖下抖 </ button >
< div id ="shakeBox3" style ="position:relative;" >
< input type ="text" />
</ div >

</ body >
</ html >

demo下载:shake.rar

转载于:https://www.cnblogs.com/lecaf/archive/2011/03/29/shake.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值