requestAnimationFrame представляется недействительным - PullRequest
0 голосов
/ 06 марта 2020

Я недавно смотрел разговор Джейка Арчибальда. В своем выступлении он привел пример, в котором он говорит, что необходимо дважды использовать requestAnimationFrame для задержки применения стиля CSS для выполнения анимации CSS.

См. https://youtu.be/cCOL7MC4Pl0?t=1337

Я воспроизвел пример, чтобы проверить его, но без везения:

Коробка будет перемещаться прямо на позицию 500 пикселей, вместо перехода с 1000 пикселей на 500 пикселей.

Решение Джейка Арчибальда было предложил. используйте двухслойный вложенный requestAnimationFrame

image

Но, похоже, он не работает для меня. Почему?

Вот фрагмент кода, который должен работать, но не :

const box = document.getElementById("box");
box.addEventListener("click", ()=>{
  box.style.transform = 'translateX(500px)';
  box.style.transition = 'transform 1s ease-out';
  requestAnimationFrame(()=>{
    requestAnimationFrame(()=>{
        box.style.transform = 'translateX(250px)';
    });
  });
});
#box {
  background-color: salmon;
  height: 100px;
  width: 100px;
  cursor: pointer;
}
<div id="box">box</div>

Ответы [ 2 ]

2 голосов
/ 06 марта 2020

Как то так?

const box = document.getElementById("box");
box.addEventListener("click", ()=>{
  box.style.transform = 'translateX(500px)';
  requestAnimationFrame(()=>{
    box.style.transition = 'transform 1s ease-out';
    requestAnimationFrame(()=>{
        box.style.transform = 'translateX(250px)';
    });
  });
});
#box {
  background-color: salmon;
  height: 100px;
  width: 100px;
  cursor: pointer;
}
<div id="box">box</div>
0 голосов
/ 06 марта 2020

Я действительно ненавижу видео, поэтому я не проверил его полностью, но, конечно, у них уже был переведен этот элемент #box до того, как они назвали это javascript.

Если бы они этого не сделали, это фактически выполнить переход от translateX(0) до translateX(1000px) в течение одного кадра и сразу после перехода от того места, где он был (вероятно, недалеко от начала слева), до translateX(250px).

Так что для исправления вы можете установить начальное значение translateX в CSS.

const box = document.getElementById("box");
box.addEventListener("click", ()=>{
  box.style.transform = 'translateX(500px)';
  box.style.transition = 'transform 1s ease-out';
  requestAnimationFrame(()=>{
    requestAnimationFrame(()=>{
        box.style.transform = 'translateX(250px)';
    });
  });
});
#box {
  background-color: salmon;
  height: 100px;
  width: 100px;
  cursor: pointer;
  transform: translateX(1000px);
}
You have to scroll to the right now.
<div id="box">box</div>

Теперь вам не стоит использовать этот двойной взлом requestAnimationFrame. Вместо этого определите проблему и используйте правильное исправление (т. Е. Форсированное восстановление).

const box = document.getElementById("box");
box.addEventListener("click", ()=>{
  box.style.transform = 'translateX(500px)';

  box.offsetWidth; // force reflow so our box is translated to initial position
  box.style.transition = 'transform 1s ease-out';
  box.style.transform = 'translateX(250px)';
});
#box {
  background-color: salmon;
  height: 100px;
  width: 100px;
  cursor: pointer;
}
<div id="box">box</div>
...