Реализация эффекта встряхивания в jQuery с помощью animate - PullRequest
13 голосов
/ 09 декабря 2010

Мне дали сокращенное подмножество библиотеки jQuery, одна из ключевых функций, которые мне не хватает - это функции .effect. Однако у меня есть .animate. Мне было интересно, есть ли у кого-нибудь идеи, как мне воспроизвести анимационные функции.

Я особенно стараюсь сделать это всего несколькими строками, так как мне нужно уменьшить размер кода. Вот почему библиотека jquery настолько мала, что не имеет функций эффектов.

TLDR - я пытаюсь заменить

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

С чем-то, использующим .animate в jQuery.

Ответы [ 9 ]

45 голосов
/ 09 декабря 2010

Пока у меня есть что-то вроде этого ..

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;
};
9 голосов
/ 09 декабря 2010

На самом деле это уже реализовано таким образом под обложками, вы можете точно увидеть, как в jquery.effects.shake.js, если вы хотите скопировать только ту функциональность, которую можете.

Еще один подход к размышлению: если вы используете несколько эффектов, я бы порекомендовал загрузить jQuery UI только с теми эффектами, которые вы хотите . Для этого эффекта, не копируя функциональность самостоятельно, вам просто понадобятся jquery.effects.core.js и jquery.effects.shake.js.

8 голосов
/ 19 августа 2015

Мне очень нравится @phpslightly solution, я продолжаю его использовать. Так что здесь он обновляется до базовой формы плагина 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();
6 голосов
/ 19 августа 2013

Это, вероятно, сейчас неактуально, но я перенес эффект дрожания jQ UI как отдельный плагин jQuery. Все, что вам нужно, это jQuery, и он будет работать точно так же, как в jQ UI.

Для тех, кто хочет использовать эффект, фактически не раздувая свой проект ненужными файлами ядра jQ UI.

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

Здесь можно найти инструкцию: https://github.com/ninty9notout/jquery-shake

Думаю, я оставлю это здесь для дальнейшего использования.

3 голосов
/ 01 октября 2013

Это более чистый и плавный способ сделать анимацию.

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;
};
2 голосов
/ 31 августа 2013

Некоторое время назад я написал несколько простых анимаций 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;
};
1 голос
/ 29 июня 2013

Я не понимаю всей сложности, возникающей при воспроизведении эффекта встряхивания только с 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

EDIT: обновлен код для возврата элемента в исходное положение. По-прежнему считаю, что это самое легкое и лучшее решение проблемы.

0 голосов
/ 20 февраля 2017

Основываясь на решении производителя @el, я добавил логику умножения и сделал ее похожей на случайную встряску.

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);
}
0 голосов
/ 11 октября 2012

Это не идеально, но функционально

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