Skip to content
Advertisement

Click to go next position in live animation

I created an animation that goes from right to left, and I am trying to add some jump on click of next box button.

How can I apply it using JavaScript ?

nextBox function should apply the jump from box1 to box2 and so on… ( for example )

const nextBox = () => {
  alert("nextBox");
  // replace => Jump to next box position +=100px to right
};
body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.container {
  background-color: aqua;
  height: fit-content;
  width: 500px;
  overflow-x: hidden;
  position: relative;
}

.anim {
  animation: anim 30s infinite linear;
  display: flex;
}

.anim > .box {
  width: 90px;
  height: 90px;
  margin: 5px;
  background-color: blue;
  flex-shrink: 0;
}

.container > button {
  position: absolute;
  left: 0px;
  top: 32px;
  width: 50px;
}

@keyframes anim {
  to {
    transform: translateX(-1000px);
  }
}
<div class="container">
  <div class="anim">
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
  </div>
  <button onclick="nextBox()">next box</button>
</div>

codepen here

Advertisement

Answer

The following implementation should work since it does what you want.

Here we have another boxContainer div to apply transition to and let the animation remain on anim class wrapper div. Also we can have another div of class pseudoBox whose width we increase by 100px to fill out the empty spacing we encounter later and to keep the order of box divs constant, we keep on appending the first box class div at the end in a cyclic fashion. I have numbered the boxes for better understanding. So our original no of box divs remain constant.

let jump = 0;
const anim = document.querySelector('.anim');
const boxContainer = document.querySelector('.boxContainer');
const pseudoBox = document.querySelector('.pseudoBox');

const animate = () => {
  boxContainer.style.transform = `translate(${jump}px)`;
  pseudoBox.style.width = `${jump*-1}px`;
  boxContainer.appendChild(boxContainer.children[1]);
}

const nextBox = () => {
  jump -= 100;
  requestAnimationFrame(animate);
};
body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.container {
  background-color: aqua;
  height: fit-content;
  width: 500px;
  overflow-x: hidden;
  position: relative;
}

.anim {
  animation: anim 30s infinite linear;
}

.pseudoBox {
  flex-shrink: 0
}

.boxContainer {
  display: flex;
  transition: transform 0.2s;
}

.boxContainer>.box {
  width: 90px;
  height: 90px;
  margin: 5px;
  background-color: blue;
  flex-shrink: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
}

.container>button {
  position: absolute;
  left: 0px;
  top: 32px;
  width: 50px;
}

@keyframes anim {
  to {
    transform: translateX(-1000px);
  }
}
<div class="container">
  <div class="anim animateStuff">

    <div class="boxContainer">
      <div class="pseudoBox"></div>
      <div class="box">1</div>
      <div class="box">2</div>
      <div class="box">3</div>
      <div class="box">4</div>
      <div class="box">5</div>
      <div class="box">6</div>
      <div class="box">7</div>
      <div class="box">8</div>
      <div class="box">9</div>
      <div class="box">10</div>
      <div class="box">11</div>
      <div class="box">12</div>
      <div class="box">13</div>
      <div class="box">14</div>
      <div class="box">15</div>
      <div class="box">16</div>
    </div>
  </div>
  <button onclick="nextBox()">next box</button>
</div>
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement