将变量传递给.animate步骤函数

时间:2013-04-29 23:12:09

标签: javascript jquery variables jquery-animate

尝试将变量传递到我的步骤函数时运行到墙中以处理最终的跨浏览器回退动画。我在这里建立了一个通用的动画方法:

Animator:function(obj,aniArgs,duration,aniEasArgs,delay,stepFunction,completeFunction){
    obj.stop(true,true).animate(aniArgs,
        {duration:parseInt(duration,10),queue:false,specialEasing:aniEasArgs,
         step:function(now,fx){     
        if($.isFunction(stepFunction)){ 
                     stepFunction.apply(this,arguments); 
        };      
     },complete:function(){
        if($.isFunction(completeFunction)){   
                     completeFunction.apply(this,arguments); };}});
         };
}

这可以工作并激活所需的一切。但是我试图调用Animator函数并使用step函数为属性设置动画。这是电话:

var angle=0,            
    stepFunction=function(now,fx,angle){
    angle+=1;
        $(this).css({"-ms-transform":"rotate("+angle+"deg)"});
    };

Animator(obj,aniArgs,speed,easing,0,stepFunction,null);

传入的所有其他参数都很好并且检查得很好。 obj是动画的obj,aniArgs是一个对象文字,包含动画的所有CSS名称/值,速度是速度,easing是包含所有CSS名称/缓动值的对象文字,stepFunction是上面声明的函数变量,null表示没有完整的功能可以执行。

一切都运行良好,但我遇到了step函数的变量问题。我似乎无法获得实际步进函数内的角度值。在这一步中,我现在可以记录和fx,并且这些都运行良好,但是我无法使用初始0值传递角度,以便我可以增加它。

我出错的任何想法?谢谢!

2 个答案:

答案 0 :(得分:2)

。 。正如@ Beetroot-Beetroot在我完成输入评论之前说的那样,每次调用progress function之间的时间不一定是恒定的,并且为angle变量添加一个常量值会使你的动画看起来不对。

。 。 step事件,根据jQuery documentation,每个属性每个tick可能被调用多次,并使用一组在这种情况下并不真正有用的参数。我们一直在评论progress回调,但使用了错误的名称。我不确定jQuery是否改变了它的实现(似乎在v1.8上添加了progress函数),但出于某种原因我在脑海中有了这个“步骤”的名字。我认为令人难以置信的GreenSock's tweening library也使用了“步骤”这个名字。无论如何,在jQuery中,stepprogress的签名如下:

step:function(Number now,Tween tween):第一个参数是一个动画属性的值,第二个参数是 jQuery的补间对象(包括prop属性,以便您知道now值引用的属性。)

进度:功能(Promise animation,Number progress,Number remainingMs):第一个参数是表示动画的a jQuery promise object,第二个参数是从0到1的数字,表示百分比动画的进度和第三个参数是动画结束前的毫秒数。

。 。出于您的目的,progress事件显然是您所需要的。请务必将step属性更改为progress函数中传递给jQuery.animate的对象中的Animator

。 。您需要使用progress值(因为它是0到1之间的值,表示动画进度的百分比)作为计算每次调用时progress function内当前角度的因素:

progressFunction = function(animation, progress, lastingms) {
  var startAngle = 0, endAngle = 180;
  var angleRange = endAngle -startAngle;
  var curAngle = startAngle +(angleRange *progress);
  $(this).css({"-ms-transform":"rotate("+ curAngle +"deg)"});
};

。 。每当您需要更多值进行动画处理时,请使用相同的逻辑:

progressFunction = function(animation, progress, lastingms) {
  var startA = 0, endA = 180, rangeA = (endA -startA);
  var startX = 254, endX = 894, rangeX = (endX -startX);

  var curA = startA + rangeA *progress;
  var curX = startX + rangeX *progress;
  $(this).css({
    "-ms-transform":"rotate("+ curAngle +"deg)",
    'left': curX +'px'
  });
};

。 。如果您计划在代码的许多部分中将其用作lib,那么尝试使其以某种方式更自动是有意义的,这样您就不需要继续编写相同的逻辑。

答案 1 :(得分:0)

步骤函数的参数由动画基础结构修复 - 您无法为其添加参数,因为它由具有固定参数集的基础结构调用。你可以创建一个存根函数(有点像你做的那样)并添加参数,然后调用你自己的函数。

Animator:function(obj,aniArgs,duration,aniEasArgs,delay,stepFunction,completeFunction){
    // initialize angle
    var angle = 0;
    obj.stop(true,true).animate(aniArgs,
        {duration:parseInt(duration,10),queue:false,specialEasing:aniEasArgs,
         step:function(now,fx){     
        if($.isFunction(stepFunction)){ 
                     // convert these args into an array
                     var args = Array.prototype.slice.call(arguments, 0);
                     // add angle onto existing arguments
                     args.push(angle);
                     // call the stepFunction with new arg added on to the end
                     stepFunction.apply(this,args); 
        };      
     },complete:function(){
        if($.isFunction(completeFunction)){   
                     completeFunction.apply(this,arguments); };}});
         };
}

或者,您可以在开始设置动画的对象上使用.data()来存储动画持续时间内的任何变量。在开始动画之前在对象上设置角度,您应该能够访问它并通过引用$(this).data()从步骤函数中更新它。

这使您不必使用全局变量,并支持同时动画多个对象。

正如其他人所指出的那样,一个好的动画每次根据经过的时间计算下一个位置,而不是根据步进函数被调用的次数来计算。这样即使由于浏览器中发生的其他事情导致动画稍微落后,也可以保持准时。