1

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

例如

// 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”)。这只是为了示例。

4

2 回答 2

2

我为我的案子解决了这个问题。

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

我选择了一个“缓动”功能以实现平滑移动 - ' 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)或创建自己的

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

您可以看到它是如何工作的(尝试以非常短的间隔按下按钮)。

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

jQuery 的animate()似乎目前不支持该行为。

于 2013-08-28T13:33:33.110 回答
1

现场演示

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

举个例子:

  <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()

于 2013-08-26T10:49:47.983 回答