назад до уроку

Пересуньте м’яч по полю

важливість: 5

Нехай м’яч переміщається при натисканні на поле, туди, де був клік, ось так:

Вимоги:

  • Центр м’яча повинен збігатися з курсором миші (якщо це можливо без перетину країв поля);
  • CSS-анімація бажана, але не є обов’язковою;
  • М’яч у жодному разі не повинен перетинати межі поля;
  • При прокручуванні сторінки нічого не повинно ламатися;

Нотатки:

  • Код повинен уміти працювати з різними розмірами м’яча та поля, не прив’язуватися до будь-яких фіксованих значень.
  • Використовуйте властивості event.clientX/event.clientY, щоб вирахувати координати миші при кліці.

Відкрити пісочницю для завдання.

Спочатку ми маємо вибрати метод позиціювання м’яча.

Ми не можемо використати position:fixed для цього, оскільки прокручування сторінки переміщатиме м’яч поля.

Правильніше використовувати position:absolute і, щоб зробити позиціювання справді надійним, зробимо саме поле field позиціонованим.

Тоді м’яч буде позиціонований щодо поля:

#field {
  width: 200px;
  height: 150px;
  position: relative;
}

#ball {
  position: absolute;
  left: 0; /* по відношенню до найближчого розташованого предка (field) */
  top: 0;
  transition: 1s all; /* CSS-анімація для значень left/top робить пересування м’яча плавним */
}

Далі ми маємо призначити коректні значення ball.style.left/top. Зараз вони містять координати щодо поля.

Як на зображенні:

Ми маємо event.clientX/clientY – координати натискання мишки щодо вікна браузера.

Щоб отримати значення left для м’яча після натискання мишки щодо поля, ми повинні від координати натискання мишки відняти координату лівого краю поля та ширину межі:

let left = event.clientX - fieldCoords.left - field.clientLeft;

Значення ball.style.left означає «лівий край елемента» (м’яча). І якщо ми призначимо такий left для м’яча, то його ліва межа, а не центр, буде під курсором миші.

Нам потрібно зрушити м’яч на половину його висоти вгору та половину його ширини вліво, щоб центр м’яча точно збігався з точкою натискання мишки.

У результаті значення для left буде таким:

let left = event.clientX - fieldCoords.left - field.clientLeft - ball.offsetWidth/2;

Вертикальна координата обчислюватиметься за тією ж логікою.

Слід пам’ятати, що ширина та висота м’яча має бути відома в той момент, коли ми отримуємо значення ball.offsetWidth. Це значення може бути задано в HTML або CSS.

Відкрити рішення в пісочниці.