让球在球场中移动
重要程度: 5
点击球场中任意一点,让球在球场中移动。就像这样:
要求:
- 球的中心应该恰好在点击时鼠标指针位置的下方(如果在球不越过球场边缘的情况下,能实现的话)。
- 最好添加一些 CSS 动画。
- 球不能越过场地边界。
- 页面滚动时,布局不能被破坏。
注意:
- 代码还应该适用于不同大小的球和球场,而不应该绑定到任何固定值。
- 使用
event.clientX/event.clientY
属性来获取点击坐标。
首先,我们需要选择一种定位球的方法。
我们不能使用 position:fixed
,因为滚动页面会造成球被移出球场。
所以我们应该使用 position:absolute
,并且要使定位真正可靠,应该使 field
自身具有 position:absolute
。
然后,球将相对于球场定位:
#field {
width: 200px;
height: 150px;
position: relative;
}
#ball {
position: absolute;
left: 0; /* 相对于最接近的祖先(field) */
top: 0;
transition: 1s all; /* left/top 的 CSS 动画,使球飞起来 */
}
接下来我们需要指定正确的 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 中指定。