JQuery анимация вдоль синусоиды - PullRequest
4 голосов
/ 18 октября 2011

Я потратил пару дней на это, и я сдаюсь.

Я пытаюсь заставить объект анимироваться вдоль синусоиды бесконечно.Он не должен заканчиваться после первого периода.

Основная проблема: Цикл заканчивается примерно на 1 1/3 Пи, а не просто Пи.Это дополнительное движение разрушает анимацию.

Я застрял здесь: http://jsfiddle.net/WPnQG/12/. После каждого периода он пропускает около 40 пикселей и затем продолжает свой путь.Это проблема, которую я не могу преодолеть - значения, на которых она заканчивается и перезапускается, не равны, поэтому объект кажется пропущенным.Кто-нибудь может помочь мужчине?Спасибо

Я использую jQuery Path Plugin для выполнения пути анимации - рассматриваемой синусоидальной волны.

enter image description here


Источник:

function float(dir){
    var x_current = $("div").offset().left;
    var y_current = $("div").offset().top;
    var SineWave = function() {
        this.css = function(p) {
            var s = Math.sin(Math.abs(p-1)*10);
            if (!dir){// flip the sin wave to continue traversing
               s = -s;
            }
            var x =  300 -p * 300;
            var y = s * 100 + 150;
            //var o = ((s+2)/4+0.1); //opacity change
            last_x = x;
            // add the current x-position to continue the path, rather than restarting
            return {top: y + "px", left: x_current + x + "px"};
        } 
    };

    $("div").stop().animate({
        path: new SineWave
    }, 5000, 'linear', function(){
        // avoid exceeding stack
        setTimeout(function(){float(!dir)}, 0);
    });

}

Ответы [ 6 ]

2 голосов
/ 18 октября 2011

Должен признаться, я был немного озадачен тем, как это было написано, однако я понимаю, что вы получили это из вики.Мне просто показалось странным, что волна греха вышла за пределы 2 пи до перезапуска.Обычно синусоида составляет от 0 до 2pi для полного цикла.У меня есть обновленный javascript, учитывающий это, и теперь ошибка исчезла.

function float(dir){
var x_current = $("div").offset().left;
var y_current = $("div").offset().top;
var SineWave = function() {
    this.css = function(p) {
        var pi2 = (3.1415927 * 2);
        var a = p * pi2;
        var s = Math.sin((pi2 - a)*2);
        var x =  300 * (1 - p);
        var y = s * 100 + 150;
        //var o = ((s+2)/4+0.1); //opacity change
        last_x = x;
        // add the current x-position to continue the path, rather than restarting
        return {top: y + "px", left: x_current + x + "px"};
    }
};

$("div").stop().animate({
    path: new SineWave
}, 5000, 'linear', function(){
    // avoid exceeding stack
    setTimeout(function(){float(!dir)}, 0);
});

}

float(true);

Примечание: вы можете указать, сколько синусоид завершить, изменив константу в s (1 - полная синусоида, 2 - две волны полного греха и т. Д.) Кроме того, больше нет необходимости «реверсировать» волну.

JSFiddle link: http://jsfiddle.net/P5vqG/8/

1 голос
/ 18 октября 2011

Когда я закомментирую эту строку:

setTimeout(function(){float(!dir)}, 0);

элемент останавливает движение точно на линии, отмеченной It skips here.

Похоже, что когда вы сбрасываете движение на // avoid exceeding stack, оно сбрасывает положение элемента в y = 0, в то время как сохраняет значение x элемента также как его путь движения.

Эта гипотеза подтверждается еще и тем, что когда пропускается (где-либо на оси y), элемент всегда возобновляет свое движение с y = 0. Иногда его значение y> y = 0, а иногда

Редактировать

Возвращаясь к демонстрационному синусу source , кажется, что вы можете получить вблизи бесконечной прокрутки, манипулируя строкой x= .... Посмотрев на исходный код, выяснилось, что демонстрационный скрипт был написан только для того, чтобы учесть один конкретный пример и проблемы с фиксированной шириной.

Вот рабочий пример.

Управляя числами в строке 1 и 2, вы можете указать количество пикселей для пути перемещения и замедлить путь вниз в строке 3, чтобы сделать его таким же быстрым, что и исходная демонстрация. Итак , не математически бесконечно, но на моем компьютере потребовалось добрых 45 секунд. Управляя этими конкретными линиями, вы можете сделать их настолько «бесконечными», сколько вам нужно.

window.SineWave = SineWave = function() {
    this.css = function(p) {
        s = Math.sin((p-1)*500);  // 1
        x = (5000 - p*5000) * 10; // 2
        y = s * 100 + 150;
        return {top: y + "px", left: x + "px"};
    } 
}

  $("#nyan").stop().animate(
        {path: new SineWave}, 
        50000, // 3
        "linear"
  );
0 голосов
/ 26 мая 2017

Вот решение (продемонстрированное в этой скрипке ) для создания синусоидальной волны просто с помощью четырех .animate параметров Jquery :

    $("div").animate({ left: [ '+=8%', 'linear' ],  
                       top:  [ '+=5%' , 'swing'  ]  }, 1000, null, function() {
        $(this).animate({ left: [ '+=8%', 'linear' ],  
                          top:  [ '-=5%' , 'swing'  ]  }, 1000, null, function() {
            $(this).animate({ left: [ '+=8%', 'linear' ],  
                                  top:  [ '+=5%' , 'swing'  ]  }, 1000, null, function() {
                $(this).animate({ left: [ '+=8%', 'linear' ],  
                                      top:  [ '-=5%' , 'swing'  ]  }, 1000, null, function() {

                        //(etc.)
                })                                                                                  

            })
        })
    })
0 голосов
/ 31 августа 2014

Вы можете использовать PathAnimator для анимации чего-либо на любом пути. вам нужны только координаты SVG, которые описывают ваш путь.

Демонстрационная страница

0 голосов
/ 18 октября 2011

Изменить

 return {top: y + "px", left: current_x + x + "px"}; 

на

  return {top: y + "px", left: last_x + x + "px"};

См. обновленную скрипку

0 голосов
/ 18 октября 2011

Почему вы не используете HTML5 Canvas?http://falcon80.com/HTMLCanvas/Animation/SineWave.html

...