@bekawaa

Как двигать блок по квадрату?

const block = document.querySelector(".block2");

let position = 0;
let position2 = 0;

const mover = () => {
    if (position < 450) {
        position += 15;
        block.style.top = `${position}px`;
        setTimeout(() => {
            mover();
        }, 50)
    } else if (position >= 450 && position2 < 450) {
        position2 += 15;
        block.style.left = `${position2}px`;
        setTimeout(() => {
            mover();
        }, 50);
    } else if (position2 >= 450) {
        position -= 15;
        block.style.top = `${position}px`;
        setTimeout(() => {
            mover();
        }, 50)
    }
}
mover();

Как сделать, чтобы третье условие работало?
  • Вопрос задан
  • 192 просмотра
Решения вопроса 1
0xD34F
@0xD34F
Как сделать, чтобы третье условие работало?

Усилить первое условие так, чтобы оно не становилось истинным после того, как перестаёт быть истинным второе.

Только вам это мало чем поможет - кривое условие не только первое, но и третье.
А всего их должно быть четыре.

const rectLeftTop = [ 50, 50 ];
const rectSize = 450;
const step = 15;
let [ x, y ] = rectLeftTop;

setInterval(() => {
  if (rectLeftTop[1] <= y && x === rectLeftTop[0]) {
    y = Math.min(y + step, rectLeftTop[1] + rectSize);
  }

  if (rectLeftTop[0] <= x && y === rectLeftTop[1] + rectSize) {
    x = Math.min(x + step, rectLeftTop[0] + rectSize);
  }

  if (rectLeftTop[1] < y && x === rectLeftTop[0] + rectSize) {
    y = Math.max(y - step, rectLeftTop[1]);
  }

  if (rectLeftTop[0] < x && y === rectLeftTop[1]) {
    x = Math.max(x - step, rectLeftTop[0]);
  }

  block.style.left = `${x}px`;
  block.style.top = `${y}px`;
}, rectSize / step);

https://jsfiddle.net/efzcpda7/

Хотя есть вариант обойтись одним.

const directions = [
  [  0, -1 ],
  [ -1,  0 ],
  [  0,  1 ],
  [  1,  0 ],
];
let iDirection = 0;

const coords = [ 50, 50 ];
const step = 15;
const rectSize = 450;
const rect = [ [...coords], coords.map(n => n + rectSize) ];

(function move() {
  const d = directions[iDirection].map(n => n * step);
  coords.forEach((n, i, a) => a[i] = Math.max(rect[0][i], Math.min(rect[1][i], n + d[i])));

  if (coords.every((n, i) => rect.some(m => m[i] === n))) {
    iDirection = (iDirection + 1) % directions.length;
  }

  block.style.left = `${coords[0]}px`;
  block.style.top = `${coords[1]}px`;

  requestAnimationFrame(move);
})();

https://jsfiddle.net/efzcpda7/1/

Но вообще - никакие условия не нужны.

Можно задать блоку transition, определить массив конечных координат и устанавливать следующие после достижения предыдущих (событие transitionend):

.block {
  transition: all 750ms linear;
}

const positions = [
  [  50,  50 ],
  [  50, 500 ],
  [ 500, 500 ],
  [ 500,  50 ],
];
let iPosition = -1;

move();
block.addEventListener('transitionend', move);
setTimeout(move, 0);

function move() {
  iPosition = (iPosition + 1) % positions.length;
  const [ x, y ] = positions[iPosition].map(n => `${n}px`);
  block.style.left = x;
  block.style.top = y;
}

https://jsfiddle.net/efzcpda7/2/

Да и в целом, JS не нужен - перемещения блока можно описать в CSS.

.block {
  animation: move 3s infinite linear;
}

@keyframes move {
  0%, 100% {
    left: 50px;
    top: 50px;
  }
  25% {
    left: 50px;
    top: 500px;
  }
  50% {
    left: 500px;
    top: 500px;
  }
  75% {
    left: 500px;
    top: 50px;
  }
}

https://jsfiddle.net/efzcpda7/3/

Если подумать, то и стили тоже лишние - с задачей отлично справляется SVG.

<svg viewBox="0 0 550 550" xmlns="http://www.w3.org/2000/svg" width="550" height="550">
  <rect width="50" height="50" fill="red">
    <animateMotion
      dur="3s"
      repeatCount="indefinite"
      path="M50,50 L50,500 L500,500 L500,50 L50,50 z"
    />
  </rect>
</svg>

https://jsfiddle.net/efzcpda7/4/
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы