更新元素之间的距离
Update Distance Between Elements
我有两个元素,一个正在走向另一个。我正试图在它靠近时获得新的距离。考虑以下代码:
<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>
当公牛到达距坐骑 3 像素以内时,没有任何反应...我已经尽可能地解释了这个问题。
**
当公牛到达距坐骑 3 像素以内时,什么也没有发生……我已经尽可能地解释了这个问题。**
好吧,我又试了一点,你的逻辑似乎不符合你想做的事情。首先,您可能注意到您在日志中的值没有改变。
这可能是因为值是在循环外检索的,但不仅如此(它们实际上必须在循环中才能更新)。您还有另外两个问题:首先,您正在测量元素的宽度和高度,它们没有考虑边距或其他定位。您的元素不会改变大小,因此值也不会。另一个问题实际上是运动上的过渡本身。由于延迟,您的所有循环迭代很可能已完成,并且当您的 "bull" 有效开始移动时,边距已设置为其最终值。这意味着在循环中,您无法检测到位置变化,元素尚未开始移动。使用刚刚设置的值(边距)而不是检测元素的真实位置应该显示值的进展,但它更难检测碰撞,因为你的 2 个元素没有相同的定位规则,你可以'只比较边距。
这是一个获取更新值的快速示例(因为转换已被禁用,如果启用返回,问题又来了)。您会注意到您对碰撞的计算也是错误的。你不能只比较两个角之间的距离,对于一个矩形它是 "has gone beyond left vertical edge AND has gone beyond top horizontal edge" (当然这只考虑左上角,为了完整,还应该补充一点,它不能已经到达右侧或底部边缘)。
好吧,我无法为您提供一个万能的解决方案,但这解决了您的代码主要问题:
<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>
EDIT/SUGGESTION:我建议查看 window.requestAnimationFrame()
MDN doc here 以获得更好的动画控制
我有两个元素,一个正在走向另一个。我正试图在它靠近时获得新的距离。考虑以下代码:
<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>
当公牛到达距坐骑 3 像素以内时,没有任何反应...我已经尽可能地解释了这个问题。 ** 当公牛到达距坐骑 3 像素以内时,什么也没有发生……我已经尽可能地解释了这个问题。**
好吧,我又试了一点,你的逻辑似乎不符合你想做的事情。首先,您可能注意到您在日志中的值没有改变。
这可能是因为值是在循环外检索的,但不仅如此(它们实际上必须在循环中才能更新)。您还有另外两个问题:首先,您正在测量元素的宽度和高度,它们没有考虑边距或其他定位。您的元素不会改变大小,因此值也不会。另一个问题实际上是运动上的过渡本身。由于延迟,您的所有循环迭代很可能已完成,并且当您的 "bull" 有效开始移动时,边距已设置为其最终值。这意味着在循环中,您无法检测到位置变化,元素尚未开始移动。使用刚刚设置的值(边距)而不是检测元素的真实位置应该显示值的进展,但它更难检测碰撞,因为你的 2 个元素没有相同的定位规则,你可以'只比较边距。
这是一个获取更新值的快速示例(因为转换已被禁用,如果启用返回,问题又来了)。您会注意到您对碰撞的计算也是错误的。你不能只比较两个角之间的距离,对于一个矩形它是 "has gone beyond left vertical edge AND has gone beyond top horizontal edge" (当然这只考虑左上角,为了完整,还应该补充一点,它不能已经到达右侧或底部边缘)。
好吧,我无法为您提供一个万能的解决方案,但这解决了您的代码主要问题:
<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>
EDIT/SUGGESTION:我建议查看 window.requestAnimationFrame()
MDN doc here 以获得更好的动画控制