jQuery 沿正弦波制作动画

发布于 2024-12-10 20:45:07 字数 1414 浏览 0 评论 0原文

我为此花了几天时间,然后放弃了。

我试图让一个对象沿着正弦波无限地产生动画。它不应该在第一个周期之后结束。

主要问题:循环在大约 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);
    });

}

I've spent a couple days at this and I give up.

I'm trying to get an object to animate along a sine wave infinitely. It should not end after the first period.

Main Problem: The cycle ends at approx 1 1/3 Pi rather than just Pi. This extra movement ruins the animation.

I'm stuck here: http://jsfiddle.net/WPnQG/12/. After each period, it skips about 40 pixels and then continues along its path. This is the problem I can't get past -- the value it ends at and proceeds to restart at are not equal, so the object appears to skip around. Could anyone help a man out? Thanks

I am using the jQuery Path Plugin to perform the path of the animation -- the sine wave in question.

enter image description here


Source:

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

云裳 2024-12-17 20:45:08

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

演示页面

You can use PathAnimator to animate anything along any path. you only need the SVG coordinates that describe your path.

Demo Page

不可一世的女人 2024-12-17 20:45:08

这是解决方案(在此fiddle) 只需使用 Jquery 的 四个 .animate 参数

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

            })
        })
    })

Here's a solution (demonstrated in this fiddle) to making a Sinusoidal Wave just by using Jquery's 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.)
                })                                                                                  

            })
        })
    })
假情假意假温柔 2024-12-17 20:45:08

更改

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

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

查看更新的小提琴

Change

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

to

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

See an updated fiddle

筱果果 2024-12-17 20:45:07

我必须承认我对这是如何编写的有点困惑,但我确实明白你是从维基上得到的。让我感到奇怪的是,正弦波在重新开始之前就超过了 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 中的常数来告诉它要完成多少个正弦波(1 是一个完整的正弦波,2 是两个完整的正弦波等)此外,不再需要“反转”波。

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

I must confess i was a bit confused about how this was written however i do understand you got it from the wiki. It just struck me as odd that the sin wave went beyond 2 pi before restarting. Typically a sin wave is from 0 to 2pi for a complete loop. I have some updated javascript taking this into account and the hiccup is now gone.

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

Note: you can tell it how many sin waves to complete by changing the constant in s (1 is one full sin wave, 2 is two full sin waves, etc.) Also, there is no more need to "reverse" the wave.

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

我不咬妳我踢妳 2024-12-17 20:45:07

当我注释掉这一行时:

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

元素恰好在标记为“它跳过此处”的行上停止运动。

看起来,当您将运动重置为//避免超出堆栈时,它会将元素的位置重置为 y=0,同时保留元素的 x 值及其运动路径。

该假设得到进一步验证,因为每当发生跳跃(y 轴上的任何位置)时,元件总是从 y=0 恢复其运动。有时它的y值> y = 0,但有时 < y = 0——因此看起来是随机的“跳来跳去”。

编辑

回到源正弦演示,看来你可以接近 通过操作 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"
  );

When I comment out this line:

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

the element stops motion precisely on the line marked It skips here.

It appears that when you reset the motion to // avoid exceeding stack it resets the position of the element to to y=0, while preserving the x value of the element as well as its path of motion.

This hypothesis is further validated in that when ever a skip occurs (anywhere on the y axis) the element always resumes its motion from y=0. Sometimes its y value is > y = 0 while sometimes it is < y = 0 -- thus the random looking "skipping around."

Edit

Going back to the source sine demo, it seems you can get near infinite scrolling, by manipulating the x= ... line. After some looking at the original source, it appears that the demo script was only written to accommodate that one specific example and fixed width problems.

Here is a working example.

By manipulating the numbers on line 1 and 2 you can specify the number of pixels for the path to traverse, and the slow the path down on line 3 to make it the same speed as the original demo. So, not mathematically infinite, but it took a good 45 seconds to complete on my computer. By manipulating these specific lines you can make it as "infinite" as you need.

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"
  );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文