【问题标题】:jQuery animating along a sine wavejQuery沿正弦波动画
【发布时间】:2011-10-18 03:55:29
【问题描述】:

我花了几天的时间,我放弃了。

我正在尝试让一个对象无限地沿着正弦波进行动画处理。它不应该在第一个周期之后结束。

主要问题:循环在大约 1 1/3 Pi 处结束,而不仅仅是 Pi。这个额外的动作会破坏动画。

我被困在这里:http://jsfiddle.net/WPnQG/12/。在每个周期之后,它会跳过大约 40 个像素,然后沿着它的路径继续前进。这是我无法解决的问题——它结束的值和重新启动的值不相等,所以对象似乎跳过了。任何人都可以帮助一个人吗?谢谢

我正在使用jQuery Path Plugin 来执行动画的路径——有问题的正弦波。


来源:

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

}

【问题讨论】:

  • 我可以问你为什么打电话给float(true,false),即使float(dir) 只接受一个参数?只是想学JS
  • 我正在测试一些东西,但因为我删除了参数而忘记了把它去掉,除了可能在 IE 中抛出一个错误之外什么都不会做

标签: jquery animation bezier trigonometry


【解决方案1】:

我必须承认,我对这是如何编写的有点困惑,但我明白你是从 wiki 获得的。令我感到奇怪的是,正弦波在重新启动之前超过了 2 pi。对于一个完整的循环,典型的正弦波是从 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 中的常数告诉它完成多少个 sin 波(1 是一个完整的 sin 波,2 是两个完整的 sin 波,等等)而且,不再需要“反转”波。

JSFiddle 链接:http://jsfiddle.net/P5vqG/8/

【讨论】:

  • 干得好,加里。是的,它继续超过终点不是很奇怪吗?我使用了 Mike 的解决方案,但我肯定会保留这个方便,以防我改变周围的东西。感谢您的投入,这确实教会了我一两件事。荣誉 +1
  • :) 我确实很欣赏您的回复,但我现在可以很容易地看出为什么它以前无法正常工作。赞赏。
【解决方案2】:

当我注释掉这一行时:

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

元素在标记为It skips here 的行上精确停止运动。

看来,当您将运动重置为// avoid exceeding stack 时,它重置元素的位置为 y=0,而 保留元素的 x 值以及它的运动路径。

这个假设得到了进一步验证,即当发生跳跃时(y 轴上的任何位置),元素总是从 y=0 恢复其运动。有时它的 y 值 > y = 0,而有时它是

编辑

回到source sine demo,通过操作x= ... 行,您似乎可以接近无限滚动。在查看了原始源代码之后,似乎只编写了演示脚本以适应一个特定的示例固定宽度问题。

Here is a working example.

通过操作第 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"
  );

【讨论】:

  • 对,我需要它从中断的地方继续。尝试了多种方法,但无法解决这个问题
  • 迈克!优秀的人,这是完美的。所以是的,你是对的,我只允许穿越一个时期。您的修复中允许多个时期的内容是什么? (按周期,我用三角法指的是一个正弦波的周期)是第 1 行还是第 2 行允许它循环不止一次?或两者?我以为第 1 行只是改变了幅度,第 2 行改变了周期的宽度,显然我错了。 +1,你就是那个男人,一直在为这个而死。
【解决方案3】:

为什么不使用 HTML5 Canvas? http://falcon80.com/HTMLCanvas/Animation/SineWave.html

【讨论】:

  • 因项目特定原因无法使用
【解决方案4】:

您可以使用PathAnimator 为任何路径上的任何内容设置动画。您只需要描述路径的 SVG 坐标。

Demo Page

【讨论】:

    【解决方案5】:

    这里是a solution(在此fiddle 中演示)只需使用Jquery 的four .animate parameters 即可制作正弦波

        $("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.)
                    })                                                                                  
    
                })
            })
        })
    

    【讨论】:

      【解决方案6】:

      改变

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

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

      查看updated fiddle

      【讨论】:

      • 不继续下一段(需要不断前行)
      • 随着时间的推移,所做的只是 X 距离的两倍,它仍然存在相同的错误。
      • 您的小提琴在大约 1 1/3 ish pi 后重置 x 值。有意?
      • 根本不是有意的。这是我认为的错误
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      • 2022-09-22
      相关资源
      最近更新 更多