我可以在jQuery中的每个动画步骤中实现回调吗?

我想在我的网站上实现一个动画:

  • 需要更新多个DOM元素。
  • 每个DOM元素都有自己的动画路径(取决于它们的位置)
  • 并且仍然有缓和效果。

如果我为每个元素调用jQuery的animate()函数(使用queue:false),它将使每个元素与其余元素略微不同步。 有道理,因为有多个计时器在运行。

我可以只有一个计时器事件,每个动画步骤都有一个回调吗? 就像是:

jQuery.fx.timeline( from, to, easing, function( step, total ) { var percentage = step / total; // ...update DOM elements based on the percentage of the animation } ); 

看看这篇文章: http : //james.padolsey.com/javascript/fun-with-jquerys-animate/

很清楚,很容易!

JavaScript中的所有计时器都基于原生普通老式JavaScript函数setInterval()setTimeout() 。 甚至jQuery也在内部使用它。

同步定时器的技巧是确保只调用一个setInterval() ,所以自己构建一些东西。

动画可以设计为:

  • 有10个步骤,每个步骤间隔30ms。
  • 总动画需要300毫秒。
  • 在每个步骤中,可以计算当前进度/百分比:

    var percentage =(currentStep / totalSteps);

现在,每次通过setInterval()调用函数时,都可以将所有DOM元素一次设置为正确的位置。 要找出元素在每个动画帧的位置,请使用:

 var diff = ( to - from ); var stepValue = from + diff * percentage; 

可以直接调用jQuery缓动函数,最终语句变为:

 var stepValue = jQuery.easing[ easingMethod ]( percentage, 0, from, diff ); 

我把它变成了一个类:

 /** * Animation timeline, with a callback. */ function AnimationTimeline( params, onstep ) { // Copy values. // Required: this.from = params.from || 0; // eg 0% this.to = params.to || 1; // eg 100% this.onstep = onstep || params.onstep; // pass the callback. // Optional this.steps = params.steps || 10; this.duration = params.duration || 300; this.easing = params.easing || "linear"; // Internal this._diff = 0; this._step = 1; this._timer = 0; } jQuery.extend( AnimationTimeline.prototype, { start: function() { if( this.from == this.to ) return; if( this._timer > 0 ) { self.console && console.error("DOUBLE START!"); return; } var myself = this; this._diff = ( this.to - this.from ); this._timer = setInterval( function() { myself.doStep() }, this.duration / this.steps ); } , stop: function() { clearInterval( this._timer ); this._timer = -1; this._queue = []; } , doStep: function() { // jQuery version of: stepValue = from + diff * percentage; var percentage = ( this._step / this.steps ); var stepValue = jQuery.easing[ this.easing ]( percentage, 0, this.from, this._diff ); // Next step var props = { animationId: this._timer + 10 , percentage: percentage , from: this.from, to: this.to , step: this._step, steps: this.steps }; if( ++this._step > this.steps ) { stepValue = this.to; // avoid rounding errors. this.stop(); } // Callback if( this.onstep( stepValue, props ) === false ) { this.stop(); } } }); 

现在你可以使用:

 var el1 = $("#element1"); var el2 = $("#element2"); var animation = new AnimationTimeline( { easing: "swing" , onstep: function( stepValue, animprops ) { // This is called for every animation frame. Set the elements: el1.css( { left: ..., top: ... } ); el2.css( { left: ..., top: ... } ); } }); // And start it. animation.start(); 

添加暂停/恢复是读者的练习。

这是一个简单的答案。 也许有人会像我一样搜索它。

我们可以在动画function中使用“step”属性。

 $(obj).animate( { left: 0 }, { duration: 50, step: function( currentLeft ){ console.log( "Left: ", currentLeft ); } } ); 

因此,对于每个步骤,这将记录当前的左侧位置

你检查了jquery队列吗?

你可以对你的动画进行排队并在每个动画上设置一个回调,我想如果你玩它很少,你可以实现你想要的。

希望它有所帮助,思南。