2 votes

Cliquez pour passer à la position suivante dans l'animation en direct

J'ai créé une animation qui va de droite à gauche, et j'essaie d'ajouter un saut au clic de la souris. boîte suivante botón.

Comment puis-je l'appliquer en utilisant JavaScript ?

nextBox doit appliquer le saut de la boîte1 à la boîte2 et ainsi de suite... ( par exemple )

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 aquí

3voto

Lakshya Thakur Points 6345

L'implémentation suivante devrait fonctionner puisqu'elle fait ce que vous voulez.

Nous avons ici un autre boxContainer div pour appliquer transition et laisser le animation rester sur anim classe wrapper div. Nous pouvons également avoir un autre div de la classe pseudoBox dont width nous augmentons de 100px pour remplir les espaces vides que nous rencontrerons plus tard et pour conserver l'ordre de l'ordre de l'arbre. box constant, nous continuons d'ajouter les éléments premièrement box div de classe à la fin, de manière cyclique. J'ai numéroté les cases pour une meilleure compréhension. Ainsi, notre nombre initial de box Les divs restent constants.

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>

2voto

sb_ Points 121

Avec ma solution, j'ai converti l'image clé css en boucle d'animation javascript. Ce n'est probablement pas ce que vous vouliez, mais j'ai trouvé qu'il était beaucoup plus facile de contrôler cette animation avec javascript, car vous vouliez passer à la case suivante, plutôt qu'à +100. J'ai utilisé des variables CSS dans le :Root pour contrôler le translateX de l'élément anim. J'espère que c'est ce que vous recherchiez

<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>next box</button>
</div>

:root {
  --tX: 'transform: translateX(0px)';
}

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 {
  transform: var(--tX);
  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;
}

const nextBtn = document.querySelector('button')

const anim = document.querySelector('.anim')
  let computed = window.getComputedStyle(anim) // get the computed style (read the transform property)

nextBtn.addEventListener('click', (e) => {
  // Get the transform property
  let transform = computed['-webkit-transform']
  // read it from the css matrix(n,n,n,n,n,n)
  //  also negate the value to make rounding easier for me
  let tX = -1 * parseInt(transform.split(',')[4].trim());

  // this gives us the translateX value

  // round up to nearest 100 - box size
  //  take 10 - account for margin
  tX = (Math.ceil(tX/100)*100) - 10

  // negate again 
  tX *= -1

  console.log(tX)

  // set our CSS variable to this value
  document.documentElement.style.setProperty('--tX', `translateX(${tX}px)`)
})

// animation loop
function loop() {
  // get the transform property each frame
  let transform = computed['-webkit-transform']
  let tX = 0;
  try {
    tX = transform.split(',')[4].trim();    
  } catch (TypeError) { 
    // probably because of being not applied in css yet
    tX = 0;
  }

  // loop the translateX - don't go below -1000
  if (tX <= -1000) {
    tX = 0;
  }

  // perform animation by subtracting 2 from translateX each frame
  document.documentElement.style.setProperty('--tX', `translateX(${tX-2}px)`)

  // perform this at 60FPS
  setTimeout(() => {
    requestAnimationFrame(loop)    
  }, 1000 / 60)
}
loop()

également un lien vers le codepen https://codepen.io/sean-b765/pen/rNjjLxM

0voto

Lichay Tiram Points 220

Après avoir vu la réponse de @Lakshya Thakur à mon message, j'ai trouvé une autre façon de le faire. avec un html et un CSS propres, sans élément pseudoBox, uniquement par JavaScript.

let jump = 0;
let index = 0;

const boxContainer = document.querySelector(".boxContainer");

const animate = () => {
  boxContainer.style.transform = `translate(${jump}px)`;
  boxContainer.appendChild(boxContainer.children[index].cloneNode(true));
  index++;
};

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;
}

.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">

    <div class="boxContainer">
      <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>

crédit à Lakshya Thakur pour la première idée

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X