Почему при вычислении координат left и top мы учитываем координаты границы и её ширину
Я пытался решить задачу "Передвиньте мяч по полю", в которой надо было переместить мяч на место клика мышки в поле. В решении использовались координаты, которые вычислялись следующим образом:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
#field {
width: 200px;
height: 150px;
position: relative;
border: 10px solid black;
background-color: #00ff00;
overflow: hidden;
cursor: pointer;
}
#ball {
position: absolute;
left: 0; /* по отношению к ближайшему расположенному предку (поле) */
top: 0;
transition: 1s all;
}
</style>
</head>
<body style="height: 2000px">
Нажмите на поле для перемещения мяча.
<br />
Мяч не должен выходить за границы поля.
<div id="field">
<img src="https://ru.js.cx/clipart/ball.svg" id="ball" /> . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
</div>
<script>
let block = document.getElementById("field");
let ball = document.getElementById("ball");
block.addEventListener("click", func);
function func() {
let fieldCoords = this.getBoundingClientRect();
let left =
event.clientX -
fieldCoords.left -
block.clientLeft -
ball.offsetWidth / 2;
let top =
event.clientY -
fieldCoords.top -
block.clientTop -
ball.offsetHeight / 2;
const cursorX = event.clientX;
const cursorY = event.clientY;
ball.style.left = left + "px";
ball.style.top = top + "px";
}
</script>
</body>
</html>
Вопрос: зачем мы в координатах left и top учитываем координаты границы и её ширину. Причем здесь это вообще ?!
Ответы (1 шт):
Автор решения: UModeL
→ Ссылка
Координаты и размеры родительского контейнера высчитываются для того, чтобы независимо от его расположения на странице, значения для дочернего блока были верными и не выходили за установленные ограничения.
Можно чуть сократить. Итоговый код такой:
let block = document.getElementById('field');
let ball = document.getElementById('ball');
block.addEventListener('click', func);
function func(ev) {
let fieldCoords = this.getBoundingClientRect();
let left = ev.clientX - fieldCoords.left - ball.offsetWidth / 2;
let top = ev.clientY - fieldCoords.top - ball.offsetHeight / 2;
if (left < 0) left = 0;
if (top < 0) top = 0;
if (left > fieldCoords.width - ball.offsetWidth) left = fieldCoords.width - ball.offsetWidth;
if (top > fieldCoords.height - ball.offsetHeight) top = fieldCoords.height - ball.offsetHeight;
ball.style.left = left + 'px';
ball.style.top = top + 'px';
}
#field { position: relative; width: 200px; height: 150px; overflow: hidden; background-color: #00ff00; cursor: pointer; }
#ball { position: absolute; left: 0; top: 0; transition: 1s all; }
<body style="height: 2000px">
Нажмите на поле для перемещения мяча.<br>Мяч не должен выходить за границы поля.
<div id="field"><img src="https://ru.js.cx/clipart/ball.svg" id="ball"></div>
</body>