javascript - CSS animation through JS slows down and then stops when using translate with rotate - Stack Overflow

const box = document.querySelector('.box');let id = undefined;function animateTest() {const s

const box = document.querySelector('.box');
let id = undefined;

function animateTest() {
  const style = window.getComputedStyle(box);
  const matrix = new DOMMatrixReadOnly(style.transform);
  const translateY = matrix.m42 + 2;
  box.style.transform = `rotate(12deg) translateY(${translateY}px)`;
  id = requestAnimationFrame(() => animateTest());
}
id = requestAnimationFrame(() => animateTest());

let button = document.querySelector('.button');
button.addEventListener('click', function() {
  cancelAnimationFrame(id);
  box.style.transform = `rotate(12deg) translateY(0px)`;
  id = requestAnimationFrame(() => animateTest());
}, false);
.box {
  margin-left: 300px;
  width: 10px;
  height: 10px;
  background-color: black;
  transform: rotate(15deg);
}
<button class='button'>rerun</button>
<div class="box"></div>

const box = document.querySelector('.box');
let id = undefined;

function animateTest() {
  const style = window.getComputedStyle(box);
  const matrix = new DOMMatrixReadOnly(style.transform);
  const translateY = matrix.m42 + 2;
  box.style.transform = `rotate(12deg) translateY(${translateY}px)`;
  id = requestAnimationFrame(() => animateTest());
}
id = requestAnimationFrame(() => animateTest());

let button = document.querySelector('.button');
button.addEventListener('click', function() {
  cancelAnimationFrame(id);
  box.style.transform = `rotate(12deg) translateY(0px)`;
  id = requestAnimationFrame(() => animateTest());
}, false);
.box {
  margin-left: 300px;
  width: 10px;
  height: 10px;
  background-color: black;
  transform: rotate(15deg);
}
<button class='button'>rerun</button>
<div class="box"></div>

Here is jsfiddle demonstrating the problem:-

jsfiddle

Reload or save to rerun animation.

I am trying to move a box 12 degrees straight using translateY but when I add rotate to make it go that direction, the animation runs for a while and then it stops moving.

I think the requestAnimationFrame is called but the translateY property stops working.

If i remove the rotate(..) it works indefinitely as normal.

Why it slows and and stops when using rotate and how to make it not do that? thank you.

More simplified example-

My Html:

<div class="box">
 
</div>

My CSS:

.box {
  margin-left: 300px;
  width: 10px;
  height: 10px;
  background-color: black;
  transform: rotate(15deg);
}

My Script:

let box = document.querySelector('.box');
function animate() {
  const style = window.getComputedStyle(box);
  const matrix = new DOMMatrixReadOnly(style.transform);
  const translateY = matrix.m42 + 2;
  box.style.transform = `rotate(12deg) translateY(${translateY}px)`;
  requestAnimationFrame(() => animate());
}
requestAnimationFrame(() => animate());
Share Improve this question edited Mar 28 at 0:24 Kaiido 138k14 gold badges259 silver badges324 bronze badges asked Mar 27 at 17:27 Sidharth BajpaiSidharth Bajpai 3623 silver badges15 bronze badges 3
  • 1 I don't know 3d matrix transforms well enough to understand why, but matrix.m42 + 2 eventually reaches a point where using it as the value for translateY gives you the same value when you run it through the matix. – Quentin Commented Mar 27 at 17:35
  • @Quentin Oh okay, thank you for pointing me in right direction! That must definitely be the reason. – Sidharth Bajpai Commented Mar 27 at 17:37
  • 1 That's because you first rotate then translate, so the translation is itself "rotated" and thus doesn't correspond to a raw translateY anymore. If you look at the e or m41 member of your matrix you can see it doesn't stay to 0, even though you didn't set a translateX. If you did first translate then rotate you wouldn't have had the same issue, but you wouldn't have had the same animation either, so it's hard to tell what fits your needs the best. – Kaiido Commented Mar 28 at 0:23
Add a comment  | 

1 Answer 1

Reset to default 0

Using @Quentin's advice in comments, as a workaround I am able to make it work using translateY as an external property, instead of getting previous one from DomMatrix.

const box = document.querySelector('.box');
let id = undefined;
let translateY = 0;

function animateTest() {
  box.style.transform = `rotate(12deg) translateY(${translateY}px)`;
  translateY = translateY+2;
  id = requestAnimationFrame(() => animateTest());
}
id = requestAnimationFrame(() => animateTest());

let button = document.querySelector('.button');
button.addEventListener('click', function() {
  cancelAnimationFrame(id);
  translateY = 0;
  id = requestAnimationFrame(() => animateTest());
}, false);

setTimeout(()=> {cancelAnimationFrame(id)}, 5000);
.box {
  margin-left: 300px;
  width: 10px;
  height: 10px;
  background-color: black;
  transform: rotate(15deg);
}
<button class='button'>rerun</button>
<div class="box"></div>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744076829a4554555.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信