jQuery animating along a sine wave

前端 未结 6 1739
-上瘾入骨i
-上瘾入骨i 2021-01-20 01:02

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.

相关标签:
6条回答
  • 2021-01-20 01:18

    Why don't you use HTML5 Canvas? http://falcon80.com/HTMLCanvas/Animation/SineWave.html

    0 讨论(0)
  • 2021-01-20 01:18

    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.)
                    })                                                                                  
    
                })
            })
        })
    
    0 讨论(0)
  • 2021-01-20 01:18

    Change

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

    to

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

    See an updated fiddle

    0 讨论(0)
  • 2021-01-20 01:19

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

    Demo Page

    0 讨论(0)
  • 2021-01-20 01:20

    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"
      );
    
    0 讨论(0)
  • 2021-01-20 01:25

    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/

    0 讨论(0)
提交回复
热议问题