简体   繁体   English

用animate实现jQuery的抖动效果

[英]Implementing jQuery's shake effect with animate

I've been given a cut down subset of the jQuery lib one of the key features I'm missing is the .effect functions.我得到了 jQuery lib 的一个缩减子集,我缺少的一个关键特性是.effect函数。 I do however have .animate .但是我确实有.animate I was wondering if anyone would have any ideas how I could go about reproducing the animation functions.我想知道是否有人对我 go 如何重现 animation 函数有任何想法。

I am particularly consious of making this only a few lines as I need to keep the code size down.我特别注意只写几行,因为我需要减少代码大小。 Which is why the jquery lib is as small as it is and doesnt have the effects functions.这就是为什么 jquery 库如此小并且没有效果函数的原因。

TLDR - I'm trying to replace TLDR - 我正在尝试更换

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

With something using .animate within jQuery.在 jQuery 内使用.animate的东西。

So far I have something like this ..到目前为止,我有这样的事情..

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;
};

I like @phpslightly solution so much, I keep using it.我非常喜欢@phpslightly 解决方案,我一直在使用它。 So here it is updated to basic jquery plugin form which will return your element所以这里它更新为基本的 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);
}

You would then use it like a regular plugin:然后,您可以像使用常规插件一样使用它:

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

Or use the default values (100, 10, 3):或者使用默认值 (100, 10, 3):

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

It's actually already implemented this way under the covers, you can see exactly how in jquery.effects.shake.js , if you wanted to copy only that functionality you can.它实际上已经在jquery.effects.shake.js以这种方式实现了,如果您只想复制该功能,您可以在jquery.effects.shake.js确切地看到它是如何实现的。

Another approach to think about: if you're using multiple effects, I'd recommend downloading jQuery UI with only the effects you want .另一种考虑的方法:如果您使用多种效果,我建议您下载仅包含您想要的效果的 jQuery UI For this effect, without copying the functionality yourself, you would just need jquery.effects.core.js and jquery.effects.shake.js .对于这种效果,无需自己复制功能,您只需要jquery.effects.core.jsjquery.effects.shake.js

This is probably irrelevant now but I've ported jQ UI's shake effect as a standalone jQuery plugin.现在这可能无关紧要,但我已经将 jQ UI 的抖动效果移植为一个独立的 jQuery 插件。 All you need is jQuery and it will work exactly like the one provided in jQ UI.您所需要的只是 jQuery,它的工作方式与 jQ UI 中提供的完全一样。

For those who want to use the effect without actually bloating their project with unnecessary jQ UI core files.对于那些想要使用效果而不用不必要的 jQ UI 核心文件实际膨胀他们的项目的人。

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

It can be found here with instruction: https://github.com/ninty9notout/jquery-shake可以在此处找到并附有说明: https : //github.com/ninty9notout/jquery-shake

Thought I'd leave this here for future reference.以为我会把它留在这里以备将来参考。

This is a more clean and smooth way to do the animation.这是一种更干净、更流畅的动画制作方式。

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;
};

I don't understand all the complexity being thrown into reproducing the shake effect with solely animate .我不明白只用animate重现摇晃效果的所有复杂性。 Here's my solution in just a couple lines.这是我的解决方案,只需几行。

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

EDIT: Updated code to return element to original position.编辑:更新代码以将元素返回到原始位置。 Still believe this is the lightest and best solution to the problem.仍然相信这是解决问题的最轻巧和最好的解决方案。

I wrote some time ago a few simple jquery animations:前段时间写了几个简单的jquery动画:

https://github.com/yckart/jquery-custom-animations 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;
};

This is not perfect, but functional这并不完美,但功能齐全

    // 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;
    }

Based on @el producer solution, I added some multiply logic and make it look like a random shake.基于@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);
}

Position had to be absolute on my side, so I changed it to: Position 必须是绝对的,所以我将其更改为:

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);
  for (var iter=0;iter<(times+1);iter++) {
    jTarget.animate({ 'padding-left': ((iter%2==0 ? distance : distance*-1))}, interval);
  }
  return jTarget.animate({ 'padding-left': 0 } ,interval);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM