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.
Why don't you use HTML5 Canvas? http://falcon80.com/HTMLCanvas/Animation/SineWave.html
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.)
})
})
})
})
Change
return {top: y + "px", left: current_x + x + "px"};
to
return {top: y + "px", left: last_x + x + "px"};
See an updated fiddle
You can use PathAnimator to animate anything along any path. you only need the SVG coordinates that describe your path.
Demo Page
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."
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"
);
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/