javascript – Element animation (flying inside parent div)

Question:

The essence of the issue is the chaotic movement of elements inside the parent div with a change in direction when it reaches the edge of the parent.

I found this script:

$(document).ready(function() {
  animateDiv($('.a'));
  animateDiv($('.b'));
  animateDiv($('.c'));

});

function makeNewPosition($container) {

  // Get viewport dimensions (remove the dimension of the div)
  var h = $container.height() - 50;
  var w = $container.width() - 50;

  var nh = Math.floor(Math.random() * h);
  var nw = Math.floor(Math.random() * w);

  return [nh, nw];

}

function animateDiv($target) {
  var newq = makeNewPosition($target.parent());
  var oldq = $target.offset();
  var speed = calcSpeed([oldq.top, oldq.left], newq);

  $target.animate({
    top: newq[0],
    left: newq[1]
  }, speed, function() {
    animateDiv($target);
  });

};

function calcSpeed(prev, next) {

  var x = Math.abs(prev[1] - next[1]);
  var y = Math.abs(prev[0] - next[0]);

  var greatest = x > y ? x : y;

  var speedModifier = 0.1;

  var speed = Math.ceil(greatest / speedModifier);

  return speed;

}
div#container {
  height: 500px;
  width: 500px;
  background-color: orange;
}

div.a {
  width: 50px;
  height: 50px;
  background-color: red;
  position: fixed;
}

div.b {
  width: 50px;
  height: 50px;
  background-color: blue;
  position: fixed;
}

div.c {
  width: 50px;
  height: 50px;
  background-color: green;
  position: fixed;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div id="container">
  <div class='a'></div>
  <div class='b'></div>
  <div class='c'></div>
</div>

Which is almost perfect.

The only thing I can't figure out is how to force the elements to change direction only when they reach the edge of the parent element?

Answer:

It can be something like this:

$(document).ready(function() {
  animateDiv($('.a'));
  animateDiv($('.b'));
  animateDiv($('.c'));
});

function makeNewPosition($container) {
  var h = $container.height() - 50;
  var w = $container.width() - 50;
  var side = Math.random()>0.5 ? 0: 1;
  var nh = 8 + (side ? h*side : Math.floor(Math.random() * h));
  var nw = 8 + (side ? Math.floor(Math.random() * w) : h*side);
  return [nh, nw];
}

function animateDiv($target) {
  var newq = makeNewPosition($target.parent());
  var oldq = $target.offset();
  var speed = calcSpeed([oldq.top, oldq.left], newq);
  $target.animate({
    top: newq[0],
    left: newq[1]
  }, speed, function() {
    animateDiv($target);
  });
};

function calcSpeed(prev, next) {
  var x = Math.abs(prev[1] - next[1]);
  var y = Math.abs(prev[0] - next[0]);
  var greatest = x > y ? x : y;
  var speedModifier = 0.1;
  var speed = Math.ceil(greatest / speedModifier);
  return speed;
}
div#container {
  height: 400px;
  width: 400px;
  background-color: orange;
}

div.a {
  width: 50px;
  height: 50px;
  background-color: red;
  position: absolute;
}

div.b {
  width: 50px;
  height: 50px;
  background-color: blue;
  position: absolute;
}

div.c {
  width: 50px;
  height: 50px;
  background-color: green;
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div id="container">
  <div class='a'></div>
  <div class='b'></div>
  <div class='c'></div>
</div>

however, it is probably better to operate with directions rather than positions

Scroll to Top