虽然说的是弹簧效果,但实际上要实现的是定点坐标之间的加速和减速移动。
点到点的移动应该都知道怎么做,这里是通过设置滑动对象的left来实现的。
而减速效果,一般的做法是通过用目标值减当前值除以一个系数(一般为正整数),得到一个步长。
然后当前值加上这个步长作为新的当前值,然后反复取值直到当前值等于目标值。
由于这样得到的步长是越来越小的,而步长就是移动的值,所以就做成减速效果。
那如何做加速效果呢?
由于取不到能对应减速步长的加速的步长(或者有方法我想不到),所以我想了个方法,
一开始先把所有减速的步长算出来,放到一个数组中,作为减速时的步长,那加速的步长就是这个数组的反转了(即倒过来)。
这个部分主要在setstep()函数中,可参照代码。
其他部分在代码中都有说明。
程序代码:
code
复制代码 代码如下:
var $ = function (id) {
return string == typeof id ? document.getelementbyid(id) : id;
};
function addeventhandler(otarget, seventtype, fnhandler) {
if (otarget.addeventlistener) {
otarget.addeventlistener(seventtype, fnhandler, false);
} else if (otarget.attachevent) {
otarget.attachevent(on + seventtype, fnhandler);
} else {
otarget[on + seventtype] = fnhandler;
}
};
var class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
object.extend = function(destination, source) {
for (var property in source) {
destination[property] = source[property];
}
return destination;
}
var bounce = 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 //是否到了最大点
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 //缩放变化率有值的话重新设置范围
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 //执行移动
this._obj.style.left = (parseint(this._obj.style.left) + this._steps.shift()) + px;
//循环移动
var othis = this; this._timer = settimeout(function(){ othis.move(); }, this.time);
},
//设置步长
setstep: function() {
var itemp = parseint(this._obj.style.left);
//注意是从大到小排的
this._steps = [];
if(this.step >= 1){
var i = 0;
do{
i = (this._xt - itemp) / this.step;
//步长不能包含0
if (i == 0) { break; } else if (math.abs(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:
复制代码 代码如下:
固定范围反弹:
范围渐变反弹:
自定范围反弹:
范围:
测试代码:
复制代码 代码如下:
new bounce(idcontainer, idbounce, 250, 200);
var o = new bounce(idcontainer1, idbounce1, 250, 200, {
zoom: 20, max: 200,
onmax: function(){ o.reduce = true; o.start(200); },
onmin: function(){ o.reduce = false; o.start(0); }
});
var o2 = new bounce(idcontainer2, idbounce2, 250);
$(bb).onclick = function(){ o2.start(parseint($(aa).value) || 200); }
$(idfast).onclick = function(){ if(--o2.step$(idslow).onclick = function(){ if(++o2.step>20){o2.step=20} }
$(idzoom).onclick = function(){ o2.zoom=50; }
javascript寮圭哀