PewPewLePew
PewPewLePew

Reputation: 13

how to animate a div within a boundry

To preface, this is my first time using JQuery so i dont really know the syntax and i'm a beginning programmer in javascript and I'm new to stackoverflow too. So apologies in advance.

Also apologies in advance if this has been asked before. This should be simple, yet somehow i can't figure it out and it's a little hard to search for.

Problem: I need my animation to be moving within a div boundry that it's in.

i tried changing the window in var h and var w to the id of my container, it doesn't work:

var h = $(#ghosts).height() - 75;
var w = $(#ghosts).height() - 75;



// html
<div id="playBoxProperties">
            <div id="playBox"> // play area
              <div id="ghosts"> // container for all 8 ghosts

                <div id='g1' class="boo"> // one of the moving ghosts
                </div>

              </div>
            </div>
        </div>


// to randomize the movement

function randomPos() { 

  var h = $(window).height() - 75; // i need to change the window, to something else.
  var w = $(window).width() - 75; //  But i dont know what.

  var newH = Math.floor(Math.random() * h);
  var newW = Math.floor(Math.random() * w);

  return [newH, newW];

}

// animation to move around

function animateDiv(divID) {

  var newPos = randomPos();

  $(divID).animate({ top: newPos[0], left: newPos[1] }, 4000, function () {
    animateDiv(divID);
  });

I expect it to be inside the black box

Upvotes: 0

Views: 63

Answers (1)

Roko C. Buljan
Roko C. Buljan

Reputation: 206679

Subtract the currently iterating ghost element size from the random coordinate relative to the parent wrapper:

  • pass the parent and the animating child like randomPos($chi, $par)
  • Use Strings as your selectors. $(#ghosts); should be $('#ghosts');
  • Create a small jQuery plugin if you want: $.fn.animateGhosts. Use it like $ghosts.animateGhosts();

const rand = (min, max) => Math.random() * (max - min) + min;
const $ghostsWrapper = $('#ghosts');
const randomPos = ($chi, $par) => ({ // Randomize position
  x: ~~(Math.random() * ($par.width() - $chi.width())),
  y: ~~(Math.random() * ($par.height() - $chi.height()))
});

$.fn.animateGhosts = function() {
  function anim() {
    const pos = randomPos($(this), $ghostsWrapper);
    $(this).stop().delay(rand(100, 500)).animate({
      left: pos.x,
      top: pos.y,
    }, rand(1000, 4000), anim.bind(this));
  }
  return this.each(anim);
};

$('.boo').animateGhosts();
#ghosts {
  position: relative;
  height: 180px;
  outline: 2px solid #000;
}

.boo {
  position: absolute;
  background: fuchsia;
  width: 50px;
  height: 50px;
}
<div id="ghosts">
  <div class="boo">1</div>
  <div class="boo">2</div>
  <div class="boo">3</div>
  <div class="boo">4</div>
  <div class="boo">5</div>
  <div class="boo">6</div>
</div>

<script src="//code.jquery.com/jquery-3.4.1.js"></script>

Better performance using CSS transition and translate

Here's an example that will use the power of CSS3 to move our elements in a hardware (GPU) accelerated fashion. Notice how, when slowing down, the elements are not zigzagging to the round pixel value (since jQuery animates top and left).
Instead we'll use transition for the CSS3 animation timing and translate(x, y) for the positions:

const rand = (min, max) => Math.random() * (max - min) + min;
const $ghostsWrapper = $('#ghosts');
const randomPos = ($chi, $par) => ({ // Randomize position
  x: ~~(Math.random() * ($par.width() - $chi.width())),
  y: ~~(Math.random() * ($par.height() - $chi.height()))
});

$.fn.animateGhosts = function() {
  function anim() {
    const pos = randomPos($(this), $ghostsWrapper);
    $(this).css({
      transition: `${rand(1, 4)}s ${rand(0.1, 0.4)}s ease`, // Speed(s) Pause(s)
      transform: `translate(${pos.x}px, ${pos.y}px)`
    }).one('transitionend', anim.bind(this));
  }
  return this.each(anim);
};

$('.boo').animateGhosts();
#ghosts {
  position: relative;
  height: 180px;
  outline: 2px solid #000;
}

.boo {
  position: absolute;
  background: fuchsia;
  width: 50px;
  height: 50px;
}
<div id="ghosts">
  <div class="boo">1</div>
  <div class="boo">2</div>
  <div class="boo">3</div>
  <div class="boo">4</div>
  <div class="boo">5</div>
  <div class="boo">6</div>
</div>

<script src="//code.jquery.com/jquery-3.4.1.js"></script>

Upvotes: 3

Related Questions