Анимация на Javascript не плавная

244
02 декабря 2018, 07:40

Подскажите, почему анимация не плавная?

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

Answer 1

Не плавная она потому, что вы каждый кадр вызываете функцию frame, в ней уже в цикле передвигаете квадрат до следующего угла, да только цикл выполнится в этом же кадре. Поэтому когда браузер снова решит отрисовать кадр, ваш квадрат уже в другом углу. И так каждый раз

Чтобы исправить, просто уберите цикл и поменяйте условия

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>

READ ALSO
Как организовать скрытие меню?

Как организовать скрытие меню?

Имеем 2 уровневое меню

167
Параметры (аргументы ) в функции

Параметры (аргументы ) в функции

Можете пожалуйста истолковать как эти параметры (аргументы) работаю в функциях ,я перечитал массу литературы , английской и русской , просто...

162
Как лучше и правильнее передать данные из javascript в сервлет, если не использовать форму и input

Как лучше и правильнее передать данные из javascript в сервлет, если не использовать форму и input

Задача стандартная, корзина на сайтеПродукты подгружаются динамически

137