我有两个元素,一个是朝向另一个元素。我正试图在靠近时获得新的距离。请考虑以下代码:
<html>
<center>
<body onload = 'start()'>
<div class='field'>
<div id='bull'></div>
<div id='mount'></div>
</div>
<button id='one'>DO</button>
</body>
</center>
<style>
.field{
width: 440px;
height: 260px;
background: rgba(0, 0, 0, .2);
margin-top: 30px;
border: 1px solid #222;
border-radius: 10px;
}
#bull{
width: 15px;
height: 10px;
background: #000;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
position: absolute;
}
#mount{
width: 60px;
height: 30px;
background: rgba(20, 10, 45);
color: #fff;
border-radius: 4px;
margin-top: 210px;
}
</style>
<script type='text/javascript'>
function start() {
var ball = document.getElementById('bull');
var button = document.getElementById('one');
var mount = document.getElementById('mount');
button.addEventListener('click', go);
var x_pos = 0;
var y_pos = 0;
var bounce_point = 200;
var ball_dim = ball.getBoundingClientRect();
var ball_h_half = ball_dim.width / 2;
var ball_w_half = ball_dim.height / 2;
var mount_dim = mount.getBoundingClientRect();
var mount_h_half = mount_dim.width / 2;
var mount_w_half = mount_dim.height / 2;
function go() {
for(x_pos = 0; bounce_point > x_pos; x_pos++) {
ball.style.margin = x_pos + "px";
ball.style.transition = x_pos/2 + "s";
var dist = ((ball_h_half - mount_h_half)*(ball_w_half - mount_w_half)) + ((mount_h_half - ball_h_half)*(mount_w_half - ball_w_half));
console.log(dist);
if(dist < 3) {
console.log('One');
}
}
}
}
</script>
当公牛到达3px的范围内时,没有任何反应......我已经尽可能地解释了这个问题。 ** 当公牛到达3px的范围内时,没有任何反应......我已经尽可能地解释了这个问题。**
答案 0 :(得分:1)
嗯我尝试了一点,你的逻辑似乎不适合你想做的事情。首先,您可能已经注意到日志中的值不会改变。
原因可能是因为值在循环外部进行了检索,但不仅仅是(它们实际上必须在循环中进行更新)。您还有其他两个问题:首先,您要测量元素的宽度和高度,而不考虑边距或其他定位。您的元素不会更改大小,因此值也不会。另一个问题实际上是运动过渡本身。由于延迟,所有循环迭代很可能完成,并且当“公牛”有效地开始移动时,保证金已经设置为其最终值。这意味着在循环中,您无法检测到位置变化,即尚未开始移动的元素。使用刚刚设置的值(边距)而不是检测元素的实际位置应该显示值的进展,但是由于你的2个元素没有相同的定位规则而且你可以更难检测到碰撞只是比较边距。
以下是一个获取更新值的快速示例(因为已禁用转换,如果启用了,则问题再次出现)。您会注意到碰撞的计算也是错误的。你不能仅仅比较两个角之间的距离,对于一个矩形而言,它“超出了左边的垂直边缘并超出了顶部水平边缘”(这当然只考虑左上角,完整,还应该补充说它还没有到达右边缘或下边缘。)
好吧,我不能为您提供一个全面的解决方案,但这解决了您的代码主要问题:
<html>
<center>
<body onload = 'start()'>
<div class='field'>
<div id='bull'></div>
<div id='mount'></div>
</div>
<button id='one'>DO</button>
</body>
</center>
<style>
.field{
width: 440px;
height: 260px;
background: rgba(0, 0, 0, .2);
margin-top: 30px;
border: 1px solid #222;
border-radius: 10px;
}
#bull{
width: 15px;
height: 10px;
background: #000;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
position: absolute;
}
#mount{
width: 60px;
height: 30px;
background: rgba(20, 10, 45);
color: #fff;
border-radius: 4px;
margin-top: 210px;
}
</style>
<script type='text/javascript'>
function start() {
var ball = document.getElementById('bull');
var button = document.getElementById('one');
var mount = document.getElementById('mount');
button.addEventListener('click', go);
var x_pos = 0;
var y_pos = 0;
var bounce_point = 200;
var ball_dim, ball_x, ball_y, mount_dim, mount_x, mount_y, diff_x, diff_y;
var stayInLoop = true;
//ball.style.transition = "0.4s"; //i don't know why you updated the transition time based on position, changed to a fixed value outside the loop because it's quicker for the example
function go() {
for(x_pos = 0; bounce_point > x_pos && stayInLoop; x_pos++) {
ball_dim = ball.getBoundingClientRect();
ball_y = ball_dim.top + 10; // +10 because we're considering the bottom edge of bull
ball_x = ball_dim.left + 15; // +15 because we're considering the right edge of bull
mount_dim = mount.getBoundingClientRect();
mount_y = mount_dim.top;
mount_x = mount_dim.left;
diff_x = mount_x - ball_x;
diff_y = mount_y - ball_y;
console.log(diff_x, diff_y);
ball.style.margin = x_pos + "px";
if(diff_x < 3 && diff_y < 3) {
console.log('One');
stayInLoop = false;
}
}
}
}
</script>
编辑/建议:我建议查看window.requestAnimationFrame()
MDN doc here以更好地控制动画