Tell me why the animation is not smooth?

window.addEventListener('DOMContentLoaded', () => { let btn = document.getElementsByTagName('button')[0]; function myAnimation() { let box = document.querySelector('.box'), boxWidth = parseFloat(getComputedStyle(box).width), boxHeight = parseFloat(getComputedStyle(box).height), elem = document.querySelector('.square'), elemWidth = parseFloat(getComputedStyle(elem).width), elemHeight = parseFloat(getComputedStyle(elem).height), pos_top = 0, pos_left = 0, id = setInterval(frame, 100); function frame() { if(pos_top == 0 && pos_left == 0) { for(let i = 0; i < (boxWidth - elemWidth); i++) { pos_left++; elem.style.left = pos_left + 'px'; } } else if(pos_top == 0 && pos_left == 300) { for(let i = 0; i < (boxHeight - elemHeight); i++) { pos_top++; elem.style.top = pos_top + 'px'; } } else if(pos_top == 300 && pos_left == 300) { for(let i = 0; i < (boxWidth - elemWidth); i++) { pos_left--; elem.style.left = pos_left + 'px'; } } else if(pos_top == 300 && pos_left == 0) { for(let i = 0; i < (boxHeight - elemHeight); i++) { pos_top--; elem.style.top = pos_top + 'px'; } } } } btn.addEventListener('click', myAnimation); }); 

https://codepen.io/FOXY_FO/pen/wEgmry

  • because the animation works with the speed of processing the loop by the browser, you do not have time to notice it - Dmytryk
  • Maxim Lensky, he added, he began to move in the center, and not on the sides - Vlad
  • Dmytryk, I understand that, but how to fix it? - Vlad

1 answer 1

It is not smooth because you call the frame function every frame , in it you move the square to the next corner already in the loop, only the cycle will be executed in the same frame. So when the browser decides to draw the frame again, your square is already in another corner. And so every time

To fix, simply remove the cycle and change the conditions

 window.addEventListener('DOMContentLoaded', () => { let btn = document.getElementsByTagName('button')[0]; function myAnimation() { btn.removeEventListener('click', myAnimation);; // один раз нажали и хватит:) let box = document.querySelector('.box'), boxWidth = parseFloat(getComputedStyle(box).width), boxHeight = parseFloat(getComputedStyle(box).height), elem = document.querySelector('.square'), elemWidth = parseFloat(getComputedStyle(elem).width), elemHeight = parseFloat(getComputedStyle(elem).height), pos_top = 0, pos_left = 0, id = setInterval(frame, 16); function frame() { if(pos_top == 0 && pos_left < 300) { pos_left++; elem.style.left = pos_left + 'px'; } else if(pos_top < 300 && pos_left == 300) { pos_top++; elem.style.top = pos_top + 'px'; } else if(pos_top == 300 && pos_left > 0) { pos_left--; elem.style.left = pos_left + 'px'; } else if(pos_top > 0 && pos_left == 0) { pos_top--; elem.style.top = pos_top + 'px'; } } } btn.addEventListener('click', myAnimation); }); 
 button:focus, input:focus { outline: none; } .box { position: relative; width: 400px; height: 400px; border: 3px solid #FF646E; } .square { position: absolute; left: 0; top: 0; width: 100px; height: 100px; background-color: #7C73FF; } .animate { width: 150px; height: 60px; margin-bottom: 10px; font-family: sans-serif; font-size: 18px; background-color: #D0FF00; border: none; cursor: pointer; } 
 <button class="animate">Animate</button> <div class="box"> <div class="square"></div> </div> 

  • +1 Press the button several times :). - Igor
  • @Igor Well, the TC also does not have filtering per click, so I did not write about it) - ThisMan
  • I suspect that this will be the next question of the vehicle. - Igor
  • @Igor corrected) - ThisMan