views:

66

answers:

3

Final Edit: The wall of text below can be summed up by simply asking "can I specify the speed of animations using jQuery's animate()? All that is provided is duration."

~~

jQuery's animate() seems to implement easing despite my use of "linear". How can I get the two boxes to stay together until the first finishes @ 250px? The second animates much faster because it has a longer distance to go.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">
    $(function()
    {
        $('#a').animate({left: '250px'}, 1000, 'linear');
        $('#b').animate({left: '500px'}, 1000, 'linear');
    });
</script>

<div id="a" style="background-color: red; position: relative; width: 50px; height: 50px;"></div>
<br/><br/>
<div id="b" style="background-color: red; position: relative;width: 50px; height: 50px;"></div>

Alternatively is there a jQuery carousel plugin that does this (mouse movement based on where you're mousing) so I don't have to rewrite it? I spent about 20 minutes looking for one on Google but couldn't come up with anything I liked.

ETA: The example I provided is very simple, but the issue as I found it is applied to a more complex code base. (1) Go here. (2) Put mouse on C. Viper, see the speed. (3) Put mouse on Ryu, but before it finishes, move your mouse to the middle of the DIV (so it stops). (4) Put your mouse back on the left side and see how utterly slow it moves.

Calculating the differences in speed and distance seems insurmountable here. All I'm trying to do is recreate a lovely effect I saw a site use today (this site). But it's Mootools, and I'm in jQuery. =[

+1  A: 

something like this??

demo

$('#a,#b').animate({left: '250px'}, 1000, 'linear',
    function(){
       $('#b').animate({left: '500px'}, 1000, 'linear');   
    }
);
Reigel
This would start the animation for the second *after* the first finishes...I believe the OP wants them to stay together until the first finishes, then `#b` to continue animating the remaining 250px.
Nick Craver
@nick - my demo and yours are just almost the same... take a look http://jsfiddle.net/BFhm6/
Reigel
@Reigel - I completely missed the `#b` in the first selector, yeah this will work just fine :)
Nick Craver
+5  A: 

For the updated question:
First, here's a working demo with the behavior you want. What we're doing here is adjusting the speed based on the amount needed to move, because speed isn't an accurate description, it's the duration, moving a shorter distance over the same duration means a slower move, so we need to scale the duration with the distance we need to move. For moving backwards, it looks like this:

var oldLeft = ul.offset().left;
ul.animate({left: 0}, -oldLeft * speed, 'linear');

Since the <ul> scrolls with a negative left position, we need to move the inverse of that many pixels to get back to the beginning, so we're using -oldLeft (it's current left position).

For the forward direction, a very similar approach:

var newLeft = divWidth - ulWidth,
    oldLeft = ul.offset().left;
ul.animate({left: newLeft + 'px'}, (-newLeft + oldLeft) * speed, 'linear');

This gets the new left property, the end being the width of the <ul> minus the width of the <div> it's in. Then we subtract (it's negative so add) that from the current left position (also negative, so reverse it).

This approach gives your speed variable a whole new meaning, it now means "milliseconds per pixel" rather than the duration it did before, which seems to be what you're after. The other optimization is using that cached <ul> selector you already had, making things a bit faster/cleaner overall.


For the original question:
Keep it simple, just half the time for half the distance, like this:

$(function() {
    $('#a').animate({left: '250px'}, 500, 'linear');
    $('#b').animate({left: '500px'}, 1000, 'linear');
});

You can try a demo here

Nick Craver
Seriously, that's required? The example I provided was extremely simple, so this suggestion is fine.. But I'm having this problem on a more complex set of code, but trying to add this calculation to that code would be more complex than what I've already written. =[
Langdon
@Langdon - I'm sure we can come up with some simple solution to the problem, what's different about the actual code? Can you animate both with one animation, then in the complete callback, kick off the second leg that only involves a subset of the elements, like `#b` in this case? Something like this: http://jsfiddle.net/BVN7n/2/
Nick Craver
I updated the the question to show my true intent. A simple example was easier to get my point across. Thanks for the effort so far.
Langdon
Nick - Sorry, deleted my comment after I saw you left a comment for Reigel.
patrick dw
@Langdon - Here's a version that does what you need, adjusting the speed to match the number of pixels to move: http://jsfiddle.net/SF6yc/
Nick Craver
Thanks for the follow through. I should have realized the problem after reading "duration" 3 times in the manual. :)
Langdon
+1  A: 

linear only specifies that the animation should be done in linear increments and not speed up or slow down as it finishes. If you want the two animations to be the same speed, just double the time it takes for the animation that is twice the distance:

$('#a').animate({left: '250px'}, 1000, 'linear');
$('#b').animate({left: '500px'}, 2000, 'linear');
Mike Sherov
I updated my question showing what I'm really doing. Calculating the difference in speed/pixels seems impossible for my real code.
Langdon