javascript requestAnimationFrame конечная позиция никогда не бывает точной - PullRequest
0 голосов
/ 03 мая 2018

let pf = document.querySelectorAll('.pf');

for (let i of pf) {
  Object.assign(i.style, {
    left: '400px'
  })
}

function shiftLetters() {
  let start = performance.now();
  let dist = -400;
  let dur = 500;

  const logoAnimate = (timestamp) => {

    var runtime = timestamp - start
    var progress = Math.min(runtime / dur, 1)
    const position = progress * dist;

    if (runtime < dur) {
      for (let i = 0; i < pf.length; i++) {
        (function(i) {
          setTimeout(function() {
            pf[i].style.transform = `translate3d(${position}px,0,0)`
          }, 100 * i)
        })(i);
      }
      requestAnimationFrame(logoAnimate)
    }
  }
  requestAnimationFrame(logoAnimate)
}

document.getElementsByTagName('button')[0].addEventListener('click', shiftLetters);
#wrapper {
  display: flex;
  position: absolute;
  -webkit-transform: translate(-50%, 10%);
  transform: translate(-50%, 10%);
  top: 50%;
  left: 50%;
}

.pf {
  display: inline-block;
  position: relative;
  width: 100px;
  height: 100px;
  margin: 2px;
  background-color: red;
}

button {
  display: block;
  margin-top: 50px;
}
<div id="wrapper">
  <div class="pf"></div>
  <div class="pf"></div>
  <div class="pf"></div>
  <div class="pf"></div>
</div>
<button>animate</button>

У меня есть 4 элемента при нажатии кнопки, которые должны заканчиваться на точном расстоянии от переменной dist. Вместо этого он заканчивается случайными целыми числами и никогда точно не -400px, как указано в моей переменной dist -400. Должно быть что-то простое. Я написал переменные за пределами области видимости и т. Д.

1 Ответ

0 голосов
/ 03 мая 2018

Причина в том, что вы никогда не применяете окончательное преобразование. На последней итерации shiftLetters, когда position finally = -400 runtime больше, чем dur, поэтому вы никогда не вводите оператор if и не применяете преобразование. Слегка переработанный код ниже.

let pf = document.querySelectorAll('.pf');

for (let i of pf) {
  Object.assign(i.style, {
    left: '400px'
  })
}

function shiftLetters() {
  let start = performance.now();
  let dist = -400;
  let dur = 500;

  const logoAnimate = (timestamp) => {

    var runtime = timestamp - start
    var progress = Math.min(runtime / dur, 1)
    const position = progress * dist;

    applyTransform(position);

    if (runtime < dur) {
      requestAnimationFrame(logoAnimate)
    }
  }
  requestAnimationFrame(logoAnimate)
}

function applyTransform(position) {
  for (let i = 0; i < pf.length; i++) {
    setTimeout(function() {
      pf[i].style.transform = `translate3d(${position}px,0,0)`
    }, 100 * i)
  }
}

document.getElementsByTagName('button')[0].addEventListener('click', shiftLetters);
#wrapper {
  display: flex;
  position: absolute;
  -webkit-transform: translate(-50%, 10%);
  transform: translate(-50%, 10%);
  top: 50%;
  left: 50%;
}

.pf {
  display: inline-block;
  position: relative;
  width: 100px;
  height: 100px;
  margin: 2px;
  background-color: red;
}

button {
  display: block;
  margin-top: 50px;
}
<div id="wrapper">
  <div class="pf"></div>
  <div class="pf"></div>
  <div class="pf"></div>
  <div class="pf"></div>
</div>
<button>animate</button>
...