9

This is as much a math question as it is a coding question.

Picture this scenario:

               
                 ___________________
                 |                 |
            (#1) |  Center Object  | (#2)
                 |_________________|

               

I want the two circular objects to move away from the center object at the same speed but different distances, #1 moving to the left and #2 moving to the right.

The end product should look like this:

               
                 ___________________
                 |                 |
(#1)             |  Center Object  |                                             (#2)
                 |_________________|

               

If I simply use animate({"marginLeft:-200px"},1000) and animate({"marginLeft:1000px"},1000), #2 will move much faster because the animation times are the same (1000).

Here's where a little calculus comes in. I'm not very good at math so I don't know where exactly to start with the calculation.

How would I vary the animation time based on the distance so that they move at the same speed?

speed = 0.04;

distanceTop = 150;
distanceRight = 500;

$('#top').animate({'marginTop':0},distanceTop/speed);
$('#right').animate({'marginLeft':'500px'},distanceRight/speed);
.object {
  background:black;
  height:50px;
  margin-top:150px;
  position:absolute;
  width:50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div style="background:red;height:200px;position:absolute;width:200px">
  <div class="object" id="top"></div>
  <div class="object" id="right"></div>
</div>

jsfiddle

As you can see in this JSFiddle, the black boxes are reaching the corners of the red box at different speeds. Excuse my bad math, but how do I make them move at equal speeds?

2
  • Why is the animation going out of the box horizontally? Commented Oct 27 at 12:30
  • 1
    Your speed/distance calculations are correct, but the jQuery animation does not happen with constant speed Commented Oct 28 at 2:24

1 Answer 1

13

The issue is that the default easing of JQuery's animate() is "swing", which corresponds to an ease-in-out function. What you want is a linear interpolation.

speed = 0.04;

distanceTop = 150;
distanceRight = 500;

$('#top').animate({'marginTop':0},distanceTop/speed, "linear");
$('#right').animate({'marginLeft':'500px'},distanceRight/speed, "linear");
.object {
  background:black;
  height:50px;
  margin-top:150px;
  position:absolute;
  width:50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div style="background:red;height:200px;position:absolute;width:200px">
  <div class="object" id="top"></div>
  <div class="object" id="right"></div>
</div>

However, note that the Web Animation API is supported by all major browsers for quite some time now, so you don't need JQuery for this, and the default easing there is "linear":

speed = 0.04;

distanceTop = 150;
distanceRight = 500;

document.getElementById("top")
  .animate({'marginTop':0}, { duration: distanceTop/speed, fill: "forwards" });
document.getElementById("right")
  .animate({'marginLeft':'500px'}, { duration: distanceRight/speed, fill: "forwards" });
.object {
  background:black;
  height:50px;
  margin-top:150px;
  position:absolute;
  width:50px;
}
<div style="background:red;height:200px;position:absolute;width:200px">
  <div class="object" id="top"></div>
  <div class="object" id="right"></div>
</div>

Sign up to request clarification or add additional context in comments.

4 Comments

@scoots I know but don't you think that's not right?
It's a demonstration only. The red div being a square is there so you have a point of reference for both black divs traveling the same distance in the same time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.