zl程序教程

您现在的位置是:首页 >  后端

当前栏目

js弹簧效果代码

JS代码 效果
2023-06-13 09:14:02 时间
虽然说的是弹簧效果,但实际上要实现的是定点坐标之间的加速和减速移动。
点到点的移动应该都知道怎么做,这里是通过设置滑动对象的left来实现的。
而减速效果,一般的做法是通过用目标值减当前值除以一个系数(一般为正整数),得到一个步长。
然后当前值加上这个步长作为新的当前值,然后反复取值直到当前值等于目标值。
由于这样得到的步长是越来越小的,而步长就是移动的值,所以就做成减速效果。
那如何做加速效果呢?
由于取不到能对应减速步长的加速的步长(或者有方法我想不到),所以我想了个方法,
一开始先把所有减速的步长算出来,放到一个数组中,作为减速时的步长,那加速的步长就是这个数组的反转了(即倒过来)。
这个部分主要在SetStep()函数中,可参照代码。
其他部分在代码中都有说明。

程序代码:
Code
复制代码代码如下:

var$=function(id){
return"string"==typeofid?document.getElementById(id):id;
};


functionaddEventHandler(oTarget,sEventType,fnHandler){
if(oTarget.addEventListener){
oTarget.addEventListener(sEventType,fnHandler,false);
}elseif(oTarget.attachEvent){
oTarget.attachEvent("on"+sEventType,fnHandler);
}else{
oTarget["on"+sEventType]=fnHandler;
}
};

varClass={
create:function(){
returnfunction(){
this.initialize.apply(this,arguments);
}
}
}

Object.extend=function(destination,source){
for(varpropertyinsource){
destination[property]=source[property];
}
returndestination;
}


varBounce=Class.create();
Bounce.prototype={
//容器对象,滑动对象,原始位置,移动范围
initialize:function(container,obj,iOrigin,iRange,options){

this._obj=$(obj);//滑动对象
this._xo=parseInt(iOrigin);//中轴坐标(即原来坐标)
this._xt=0;//目标坐标
this._xs=[];//目标坐标集合
this._steps=[];//步长集合
this._fast=true;//是否加速

this.Range=iRange||0;//滑动范围(宽度)

this.SetOptions(options);

this.Step=parseInt(this.options.Step);
this.Time=parseInt(this.options.Time);
this.Zoom=parseInt(this.options.Zoom);
this.Reduce=!!this.options.Reduce;
this.Min=parseInt(this.options.Min);
this.Max=parseInt(this.options.Max);
this.onMin=this.options.onMin;
this.onMax=this.options.onMax;
this.onSide=this.options.onSide;

//样式设置
$(container).style.position="relative";
this._obj.style.position="absolute";
this._obj.style.left=this._xo+"px";

if(this.Range>0)this.Start();
},
//设置默认属性
SetOptions:function(options){
this.options={//默认值
Step:10,//滑动变化率
Time:10,//滑动延时
Zoom:0,//缩放变化率
Reduce:true,//是否缩小
Min:0,//最小范围
Max:0,//最大范围
onMin:function(){},//到达最小时执行
onMax:function(){},//到达最大时执行
onSide:function(){}//到达边界时执行
};
Object.extend(this.options,options||{});
},
//从轴点开始
Start:function(iRange){
clearTimeout(this._timer);
//iRange有值的话重新设置滑动范围
if(iRange)this.Range=iRange;
//是否到了最小点
if(this.Reduce&&(this.Range<=0||this.Range<=this.Min)){this.onMin();return;}
//是否到了最大点
if(!this.Reduce&&(this.Max>0&&this.Range>=this.Max)){this.onMax();return;}
//重置位置
this._obj.style.left=this._xo+"px";
//设置目标坐标集合(iRange可能会变化所以每次都要设置)
this._xs=[this._xo+this.Range,this._xo,this._xo-this.Range,this._xo];
//设置为加速状态
this._fast=false;
//开始分段移动
this.Set();
},
//从分段开始
Set:function(){
//目标坐标都到达后返回
if(this._xs.length<=0){
//缩放变化率有值的话重新设置范围
if(this.Zoom>0){this.Range+=(this.Reduce?-1:1)*this.Zoom;}
this.Start();return;
}
//取得目标坐标
this._xt=this._xs.shift();
//目标坐标是中轴点说明现在是在边界上
if(this._xt==this._xo)this.onSide();
//设置步长
this.SetStep();
//开始移动
this.Move();
},
//移动
Move:function(){
clearTimeout(this._timer);
//步长走完即到达目标坐标就返回
if(this._steps.length<=0){this.Set();return;}
//执行移动
this._obj.style.left=(parseInt(this._obj.style.left)+this._steps.shift())+"px";
//循环移动
varoThis=this;this._timer=setTimeout(function(){oThis.Move();},this.Time);
},
//设置步长
SetStep:function(){
variTemp=parseInt(this._obj.style.left);

//注意是从大到小排的
this._steps=[];

if(this.Step>=1){
vari=0;
do{
i=(this._xt-iTemp)/this.Step;
//步长不能包含0
if(i==0){break;}elseif(Math.abs(i)<1){i=i>0?1:-1;}
this._steps.push(i=parseInt(i));
iTemp+=i;
}while(true);
//如果是加速的话反转步长集合
if(this._fast)this._steps.reverse();
}
//加速减速是交替进行的所以每次都要取反
this._fast=!this._fast;
}
};

测试html: 
复制代码代码如下:

<styletype="text/css">
.container{border:1pxsolid#000000;height:50px;width:500px;}
.bounce{width:10px;height:10px;background:#000000;top:20px;}
</style>
固定范围反弹:
<divid="idContainer"class="container">
<divid="idBounce"class="bounce"></div>
</div>
<br/>
范围渐变反弹:
<divid="idContainer1"class="container">
<divid="idBounce1"class="bounce"></div>
</div>
<br/>
自定范围反弹:
<divid="idContainer2"class="container">
<divid="idBounce2"class="bounce"></div>
</div>
<br/>
范围:
<inputid="aa"name=""type="text"value="200"size="8"/>
<inputid="bb"name=""type="button"value="开始"/>
<inputid="idFast"name=""type="button"value="加速+"/>
<inputid="idSlow"name=""type="button"value="减速-"/>
<inputid="idZoom"name=""type="button"value="渐小"/>

测试代码:
复制代码代码如下:
newBounce("idContainer","idBounce",250,200);
varo=newBounce("idContainer1","idBounce1",250,200,{
Zoom:20,Max:200,
onMax:function(){o.Reduce=true;o.Start(200);},
onMin:function(){o.Reduce=false;o.Start(0);}
});

varo2=newBounce("idContainer2","idBounce2",250);
$("bb").onclick=function(){o2.Start(parseInt($("aa").value)||200);}
$("idFast").onclick=function(){if(--o2.Step<2){o2.Step=2}}
$("idSlow").onclick=function(){if(++o2.Step>20){o2.Step=20}}
$("idZoom").onclick=function(){o2.Zoom=50;}


javascript弹簧效果 .container{border:1pxsolid#000000;height:50px;width:500px;} .bounce{width:10px;height:10px;background:#000000;top:20px;} 固定范围反弹: 范围渐变反弹: 自定范围反弹: 范围: