0

在尝试将变量传递给我的步进函数以处理一些最终的跨浏览器后备动画时遇到了墙。我在这里建立了一个通用的动画方法:

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 名称/值,speed 是速度,easing 是一个包含所有 CSS 名称/缓动值的对象字面量,stepFunction 是上面声明的函数变量,null表示没有完整的功能可以执行。

一切都很好,但是我遇到了 step 函数的可变问题。我似乎无法在实际的阶跃函数中获得角度的值。在该步骤中,我现在可以记录和 fx,并且它们运行良好,但是我无法传递具有初始 0 值的角度,以便我可以增加它。

有什么想法我哪里出错了吗?谢谢!

4

2 回答 2

2

. . 正如@Beetroot-Beetroot 在我输入完评论前几秒钟所说的那样,每次调用之间的时间progress function不一定是恒定的,向angle变量添加恒定值会使您的动画看起来错误。

. . 根据jQuery 文档,该step事件可能在每个属性的每个刻度上调用不止一次,并且使用了一组在这种情况下并不真正有用的参数。我们一直在评论回调,但使用了错误的名称。我不确定 jQuery 是否更改了它的实现(似乎该功能是在 v1.8 上添加的),但出于某种原因,我在脑海中有了这个“步骤”名称。我认为令人难以置信的 GreenSock 补间库也使用了“步骤”名称。无论如何,在 jQuery 中,和的签名如下:progressprogressstepprogress

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

progress: function (Promise animation, Number progress, Number remainingMs):第一个参数是一个代表动画的jQuery promise对象,第二个参数是一个从0到1的数字,代表动画进度的百分比,第三个参数是数字毫秒,直到动画结束。

. . 出于您的目的,该progress活动显然是您所需要的。请记住将step属性更改为您在函数中progress传递给的对象。jQuery.animateAnimator

. . 您需要使用该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'
  });
};

. . 如果您打算在代码的许多部分中将其用作库,那么尝试使其以某种方式更加自动化是有意义的,这样您就不需要一直编写相同的逻辑。

于 2013-04-29T23:31:17.120 回答
0

step 函数的参数由动画基础结构固定 - 您不能向它添加参数,因为它是由具有一组固定参数的基础结构调用的。您可以创建一个存根函数(有点像您所做的)并添加参数,然后调用您自己的函数。

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()在对象上使用开始动画来存储动画持续时间的任何变量。在开始动画之前设置对象的角度,您应该能够通过引用从 step 函数中访问和更新它$(this).data()

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

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

于 2013-04-29T23:29:31.207 回答