【问题标题】:JQuery: how to make a superposition of many moving animations which start asynchronously?JQuery:如何叠加许多异步启动的移动动画?
【发布时间】:2013-08-26 10:37:46
【问题描述】:

我想将一个动画叠加在另一个动画上。 第二个(第三个、第四个)动画可以异步启动。为此,我需要指定新位置和旧位置之间的差异(不是绝对的“左”)。

例如

// One moment
$( '#my_div' ).animate( { 'leftShift': "+20px", 2000, 'easeOutQuad' } );

// Another moment, may be a second later
$( '#my_div' ).animate( { 'leftShift': "+50px" }, 2000, 'easeOutQuad' );

是否可以添加多个动画的结果?

阐明我想要什么的图表(X 轴:时间,Y 轴:距离变化的速度)。

我希望看到添加动画的速度,而不是逐个动画。

Roko C. Buljan 提供了什么?

但我不想要延迟动画,我想要实时动画。

注意。现在不支持当前语法(“+20px”、“+50px”)。仅作为示例。

【问题讨论】:

  • 不是,但"+=20px", "+=50px"
  • @RokoC.Buljan 它适用于“异步”情况吗?
  • 如果你使用.stop(),它会在当前动画上叠加新的动画。

标签: javascript jquery animation jquery-animate


【解决方案1】:

我解决了我的问题。

我需要非常流畅的动画。所以,当用户发起一个新的推送时,它应该是一个新的冲动。所以,之前不能停止一个对象。

我选择了一个“缓动”功能来实现平滑移动 - 'easeInOutQuad'。我实现了自己的版本(我删除了用于 jQuery 标准“缓动”选项的不必要参数):

// Some browsers works bad if there is float px

function asyncAnimate( obj, props, duration, easing )
{
    function _getTime()
    {
        var d = new Date();
        return d.getTime();
    }       

    var startTime = _getTime();
    var duration = duration;

    var animNum = asyncAnimate._animNum;

    var propInts = {}; // to increment only ints
    var propFloats = {};

    for( var iProp in props )
    {
        var sProp = obj.css( iProp );
        propFloats[ iProp ] = 0.0; // in the beginning all floats is 0
    }


    var animInterval = setInterval( 
        function()
        {
            var curTime = _getTime();

            if( curTime <= startTime + duration )
            {
                var timeDiff = curTime - startTime;
                var step = easing( timeDiff / duration, timeDiff, 0, 1, duration );

                var dStep;

                var prevStep = asyncAnimate._prevSteps[ animNum ];

                if( prevStep == null )
                {
                    dStep = step;
                }
                else
                {
                    dStep = step - prevStep;                        
                }

                asyncAnimate._prevSteps[ animNum ] = step;

                for( var iProp in props )
                {                   
                    var prop = props[ iProp ];

                    // we can increment int px only (for crossbrowser solution),
                    // so, we need to save a float part                 

                    var propStep = prop * dStep;

                    // calculate total int part
                    var savedFloatPart = propFloats[ iProp ];

                    var totalPropStep = propStep + savedFloatPart;
                    var totalPropStepInt = parseInt( totalPropStep );
                    var totalPropStepFloat = totalPropStep - totalPropStepInt;

                    if( Math.abs( totalPropStepInt ) > 0 )
                    {                                                   
                        obj.css( iProp, "+=" + String( totalPropStepInt ) + "px" );
                    }

                    // reset saved int/float parts
                    propFloats[ iProp ] = totalPropStepFloat;
                }
            }
            else
            {                   
                clearInterval( animInterval );
            }
        },
        10 
    );

    asyncAnimate._animNum++;
}

asyncAnimate._prevSteps = {};
asyncAnimate._animNum = 0;

使用示例(不要忘记包含js with easing functions)或create your own

asyncAnimate( $( '#div1' ), { 'margin-left': 50 }, 1000, $.easing.easeInOutElastic );
// ...
asyncAnimate( $( '.green' ), { 'width': -50, 'height': -50 }, 250, $.easing.easeInOutQuad );

您可以看到how it works(尝试以非常短的间隔按下按钮)。

我希望它很容易适应一些其他类型的动画。

目前看来jQuery的animate()不支持该行为。

【讨论】:

  • 你做了一个令人难以置信和惊人的工作。感谢分享这个答案。标记为正确!来自我的 +1
【解决方案2】:

LIVE DEMO

.stop() 方法将清除您当前的动画。
您可以使用+=-= 来更新当前元素位置

举例:

  <input type="button" value="50" />
  <input type="button" value="-50" />
  <input type="button" value="150" />
  <input type="button" value="-150" />


  <div id="my_div"></div>

$(':button').click(function(){
  $('#my_div').stop().animate( { left: "+="+ this.value }, 2000 );
});

如果你不需要清除之前的动画,逻辑上只需删除.stop()

【讨论】:

  • 我想在之前的动画中添加一个新动画。我不想停止我之前的动画。
  • 在您的现场演示中:我删除了“stop()”调用:$(':button').click。然后我尝试在很短的时间间隔内多次单击“-50”按钮。动画一一推出。对不起,但这不完全是。当我按下按钮时,必须开始一个新的动画。并且必须继续之前的动画。所以,速度必须提高。
  • @sergzach 如果速度必须提高到您需要应用speed 因子值的逻辑
  • @sergzach 我真的不明白你,你需要线性运动吗?速度提升?距离呢……你需要澄清你的问题才能得到正确的答案
  • 对不起,我走了。无论如何,如果不应用一些高级数学,您想要实现的目标不会那么容易。您可能需要在 animate 函数的 step 属性中注册更改。您可以找到我的另一个答案,它可能会帮助您澄清一下如何做到这一点:stackoverflow.com/questions/10568507/…
猜你喜欢
  • 2018-05-06
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
  • 1970-01-01
相关资源
最近更新 更多