JavaScript 弹簧效果

it2025-03-23  25

上次做图片 滑动展示效果时做了减速效果,就想做一个加速效果。结合起来就想到了下面这个东西,当然只是类似弹簧,而不是真正的弹簧。 先看效果: 固定范围反弹: 范围渐变反弹: 自定范围反弹: 范围: 程序说明: 虽然说的是弹簧效果,但实际上要实现的是定点坐标之间的加速和减速移动。 点到点的移动应该都知道怎么做,这里是通过设置滑动对象的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 > 0this.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";     //循环移动    var oThis = thisthis._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) < 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: Code <style type="text/css"> .container{border:1px solid #000000;height:50px; width:500px;} .bounce{width:10px; height:10px; background:#000000;top:20px;}</style> 固定范围反弹:<div id="idContainer" class="container">   <div id="idBounce" class="bounce"> </div></div><br /> 范围渐变反弹:<div id="idContainer1" class="container">   <div id="idBounce1" class="bounce"> </div></div><br /> 自定范围反弹:<div id="idContainer2" class="container">   <div id="idBounce2" class="bounce"> </div></div><br /> 范围:<input id="aa" name="" type="text" value="200" size="8" /><input id="bb" name="" type="button" value=" 开始 " /><input id="idFast" name="" type="button" value=" 加速 + " /><input id="idSlow" name="" type="button" value=" 减速 - " /><input id="idZoom" name="" type="button" value=" 渐 小 " /> 测试代码: Code     new Bounce("idContainer""idBounce"250200);          var o = new Bounce("idContainer1""idBounce1"250200, {         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<2){o2.Step=2} }     $("idSlow").onclick = function(){ if(++o2.Step>20){o2.Step=20} }     $("idZoom").onclick = function(){ o2.Zoom=50; } 下载完整测试代码

转载于:https://www.cnblogs.com/cloudgamer/archive/2008/05/17/1201386.html

相关资源:javascript经典效果示例
最新回复(0)