用 animate 实现 jQuery 的抖动效果

Posted

技术标签:

【中文标题】用 animate 实现 jQuery 的抖动效果【英文标题】:Implementing jQuery's shake effect with animate 【发布时间】:2011-05-22 21:22:13 【问题描述】:

我得到了 jQuery 库的一个缩减子集,我缺少的一个关键特性是 .effect 函数。但是我确实有.animate。我想知道是否有人对我如何重现动画功能有任何想法。

我特别注意只写几行代码,因为我需要减小代码大小。这就是为什么 jquery 库这么小而且没有效果函数的原因。

TLDR - 我正在尝试替换

 $("#"+id_string).effect( "shake", , "fast" );

在 jQuery 中使用 .animate 的东西。

【问题讨论】:

【参考方案1】:

到目前为止,我有这样的东西..

jQuery.fn.shake = function(intShakes, intDistance, intDuration) 
    this.each(function() 
        $(this).css("position","relative"); 
        for (var x=1; x<=intShakes; x++) 
        $(this).animate(left:(intDistance*-1), (((intDuration/intShakes)/4)))
    .animate(left:intDistance, ((intDuration/intShakes)/2))
    .animate(left:0, (((intDuration/intShakes)/4)));
    
  );
return this;
;

【讨论】:

所有这些括号...(((...为什么? 有人可以制作这个小提琴吗? @ŠimeVidas 他控制着那些(((s 的操作顺序 @Fresheyeball 大多数这些括号都不需要,这就是我的观点。例如,这个 - (((intDuration/intShakes)/4)) - 可以替换为这个 - intDuration/intShakes/4 - 而不会改变操作的顺序。另外,请注意双重包装 - ((expression)) - 这没有任何作用。 这只能让你摇动没有剩下的东西:设置为 0 以外的东西。【参考方案2】:

我非常喜欢@phpslightly 解决方案,我一直在使用它。所以这里它被更新为基本的 jquery 插件表单,它将返回你的元素

jQuery.fn.shake = function(interval,distance,times)
   interval = typeof interval == "undefined" ? 100 : interval;
   distance = typeof distance == "undefined" ? 10 : distance;
   times = typeof times == "undefined" ? 3 : times;
   var jTarget = $(this);
   jTarget.css('position','relative');
   for(var iter=0;iter<(times+1);iter++)
      jTarget.animate( left: ((iter%2==0 ? distance : distance*-1)), interval);
   
   return jTarget.animate( left: 0,interval);

然后您可以像使用常规插件一样使用它:

$("#your-element").shake(100,10,3);

或者使用默认值(100、10、3):

$("#your-element").shake();

【讨论】:

为什么不把默认值放在参数中呢? function (interval = 100, distance = 10, times = 1)【参考方案3】:

实际上已经在幕后以这种方式实现了,如果您只想复制该功能,您可以在jquery.effects.shake.js 中查看具体实现方式。

另一种思考方式:如果您使用多种效果,我建议您使用downloading jQuery UI with only the effects you want。对于这种效果,无需自己复制功能,您只需要jquery.effects.core.jsjquery.effects.shake.js

【讨论】:

由于我陷入了一个严重缩减的 jquery 版本,我根本无法访问效果代码。我一直在玩以下..必须将其添加为答案,因为似乎无法在回复中格式化。 @wmitchell - 我将你链接到答案中的源代码:) 新链接:jquery.ui.effect.js 和 jquery.ui.effect.shake.js 再次新建链接:effect.js 和 effect-shake.js 新链接再次effect.js和effect-shake.js【参考方案4】:

现在这可能无关紧要,但我已将 jQ UI 的抖动效果移植为独立的 jQuery 插件。您所需要的只是 jQuery,它的工作方式与 jQ UI 中提供的完全一样。

对于那些想要使用效果而不用不必要的 jQ UI 核心文件实际使项目膨胀的人。

$('#element').shake(...);

可以在这里找到说明:https://github.com/ninty9notout/jquery-shake

我想我会把它留在这里以供将来参考。

【讨论】:

为我节省了一些时间。谢谢!【参考方案5】:

这是一种更干净流畅的动画制作方式。

jQuery.fn.shake = function(shakes, distance, duration) 
    if(shakes > 0) 
        this.each(function() 
            var $el = $(this);
            var left = $el.css('left');
            $el.animate(left: "-=" + distance, duration, function()
                $el.animate(left: "+=" + distance * 2, duration, function() 
                    $el.animate(left: left, duration, function() 
                        $el.shake(shakes-1, distance, duration); ););
            );
        );
    
    return this;
;

【讨论】:

【参考方案6】:

前段时间写了几个简单的jquery动画:

https://github.com/yckart/jquery-custom-animations

/**
 * @param number times - The number of shakes
 * @param number duration - The speed amount
 * @param string easing - The easing method
 * @param function complete - A callback function
 */
jQuery.fn.shake =
jQuery.fn.wiggle = function (times, duration, easing, complete) 
    var self = this;

    if (times > 0) 
        this.animate(
            marginLeft: times-- % 2 === 0 ? -15 : 15
        , duration, easing, function () 
            self.wiggle(times, duration, easing, complete);
        );
     else 
        this.animate(
            marginLeft: 0
        , duration, easing, function () 
            if (jQuery.isFunction(complete)) 
                complete();
            
        );
    
    return this;
;

【讨论】:

你也可以试试这个codingstuffsbykiran.blogspot.com/2014/06/…【参考方案7】:

我不明白仅使用animate 来重现抖动效果所涉及的所有复杂性。这是我的解决方案,只需几行。

function shake(div,interval=100,distance=10,times=4)
    $(div).css('position','relative');
    for(var iter=0;iter<(times+1);iter++)
        $(div).animate( left: ((iter%2==0 ? distance : distance*-1)), interval);
    //for
    $(div).animate( left: 0,interval);
//shake

编辑:更新代码以将元素返回到原始位置。仍然相信这是解决问题的最简单和最好的解决方案。

【讨论】:

此解决方案不会在动画结束后将元素返回到其原始位置。【参考方案8】:

这并不完美,但很实用

    // Example: $('#<% =ButtonTest.ClientID %>').myshake(3, 120, 3, false);
    jQuery.fn.myshake = function (steps, duration, amount, vertical) 
        var s = steps || 3;
        var d = duration || 120;
        var a = amount || 3;
        var v = vertical || false;
        this.css('position', 'relative');
        var cur = parseInt(this.css(v ? "top" : "left"), 10);
        if (isNaN(cur))
            cur = 0;

        var ds = d / s;

        if (v) 
            for (i = 0; i < s; i++)
                this.animate( "top": cur + a + "px" , ds).animate( "top": cur - a + "px" , ds);
            this.animate( "top": cur , 20);
        
        else 
            for (i = 0; i < s; i++)
                this.animate( "left": cur + a , ds).animate( "left": cur - a + "px" , ds);
            this.animate( "left": cur , 20);
        

        return this;
    

【讨论】:

【参考方案9】:

基于@el producer 解决方案,我添加了一些乘法逻辑,使其看起来像随机抖动。

jQuery.fn.shake = function (interval, distance, times) 
    interval = typeof interval == "undefined" ? 100 : interval;
    distance = typeof distance == "undefined" ? 10 : distance;
    times = typeof times == "undefined" ? 3 : times;
    var jTarget = $(this);
    jTarget.css('position', 'relative');
    for (var iter = 0; iter < (times + 1) ; iter++) 
        jTarget.animate( top: ((iter % 2 == 0 ? distance * Math.random() : distance * Math.random() * -1)), left: ((iter % 2 == 0 ? distance * Math.random() : distance * Math.random() * -1)) , interval);
    
    return jTarget.animate( top: 0 , left: 0 , interval);

【讨论】:

以上是关于用 animate 实现 jQuery 的抖动效果的主要内容,如果未能解决你的问题,请参考以下文章

jQuery实现抖动效果

CSS3animation动画为啥会出现抖动效果,怎么解决

文本窗口抖动和位移效果

jquery中的animate动态效果是如何通过Js实现的?

iOS图标抖动效果

用jquery的animate动画函数做的网页效果