JavaScript实现元素拖拽与矩形碰撞检测

作者:异步漫步时间:2026-10-23 21:58:57浏览:213

本文详解JavaScript中实现元素拖拽与矩形碰撞检测的原理及代码。通过onmousedown、onmousemove和onmouseup事件处理拖拽逻辑,利用offsetLeft和offsetTop计算坐标。碰撞检测采用排除法,判断两个矩形是否重叠,提供完整可运行的HTML与JS示例代码。

本文分享使用JavaScript实现元素拖拽及碰撞检测的具体代码,供读者参考学习。

拖拽功能实现

拖拽功能实现

拖拽功能实现

核心原理分析

实现一个可拖拽的div元素,需要监听用户的鼠标交互过程:当鼠标指针移入盒子区域并点击左键时触发按下事件,随后移动鼠标改变位置,最后松开鼠标结束操作。

该过程主要涉及以下三个鼠标事件:

  • 鼠标按下事件:onmousedown
  • 鼠标移动事件:onmousemove
  • 鼠标松开事件:onmouseup

具体实现步骤如下:

1、**鼠标按下时:**首先计算鼠标点击位置相对于页面左上角的坐标,然后减去目标盒子距离页面左上角的偏移量。

由此得到鼠标点击点相对于盒子左上角的相对距离;

2、**鼠标移动时:**实时获取鼠标当前的页面坐标,并减去步骤1中计算的相对距离。

将计算结果赋值给盒子的定位属性,使盒子跟随鼠标移动并保持相对位置不变;

3、**松开鼠标时:**移除页面上的鼠标移动事件监听,停止拖拽操作。

相关实现代码见下文。


var oDiv = document.getElementById('box2');
  oDiv.onmousedown = function(ev){
   var e = ev||window.event;
   var offsetX = e.clientX - oDiv.offsetLeft;
   var offsetY = e.clientY - oDiv.offsetTop;
   document.onmousemove = function(ev){
    var e = ev||window.event;
    var l =e.clientX-offsetX;
    var t = e.clientY- offsetY;
    
    if(l<=0){
     l=0;
    }
    if(t<=0){
     t=0;
    }
    var windowWidth =document.documentElement.clientWidth||document.body.clientWidth;
    if(l>=windowWidth-oDiv.offsetWidth){
     l=windowWidth-oDiv.offsetWidth;
    }
    var windowHeight = document.documentElement.clientHeight||document.body.clientHeight
    if(t>=windowHeight-oDiv.offsetHeight){
     t=windowHeight-oDiv.offsetHeight;
    }
    oDiv.style.left = l + "px";
    oDiv.style.top = t + "px";
   }
  }
  document.onmouseup = function(){
   document.onmousemove = null;
  }

碰撞检测功能

碰撞检测功能

碰撞检测原理

在JavaScript游戏开发(如飞机大战、打砖块、贪吃蛇等)中,碰撞检测是关键技术。其核心在于判断两个物体是否发生接触。

直接判断两个矩形是否重叠较为复杂,我们可以采用逆向思维:先找出两个矩形**没有**发生碰撞的所有情况。

排除这些不重叠的情况后,剩余的情形即为发生了碰撞。

以检测方块a与方块b是否碰撞为例,我们需要获取两个矩形上、下、左、右四个边的坐标值。

拖拽功能实现

以下四种情况表示两个矩形未发生碰撞:

1、a的左边界在b的右边界右侧(a左 > b右) 2、a的上边界在b的下边界上方(a上 > b下) 3、a的右边界在b的左边界左侧(a右 < b左) 4、a的下边界在b的上边界上方(a下 < b上)

各坐标值计算方法如下: a左:a.offsetLeft; a右:a.offsetLeft + a.offsetWidth; a上:a.offsetTop; a下:a.offsetTop + a.offsetHeight; b左:b.offsetLeft; b右:b.offsetLeft + b.offsetWidth; b上:b.offsetTop; b下:b.offsetTop + b.offsetHeight;

只要满足上述四种情况中的任意一种,即可判定两个矩形没有发生碰撞;否则判定为发生碰撞。

碰撞检测的实现代码如下。


function knock(node1,node2){
   var l1 = node1.offsetLeft;
   var r1 = node1.offsetLeft + node1.offsetWidth;
   var t1 = node1.offsetTop;
   var b1 = node1.offsetTop+node1.offsetHeight;
   var l2 = node2.offsetLeft;
   var r2 = node2.offsetLeft + node2.offsetWidth;
   var t2 = node2.offsetTop;
   var b2 = node2.offsetTop+node2.offsetHeight;
   if(l2>r1||r2<l1||t2>b1||b2<t1){
    return false;
   }else{
    return true;
   }
  }

拖拽与碰撞功能的完整代码示例如下。


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #box1{
      width: 100px;height: 100px;position: absolute;
      top: 200px;left: 250px;background-color: blueviolet;
    }
    #box2{
      width: 100px;height: 100px;position: absolute;
      top: 400px;left: 550px;background-color: salmon;
    }
  </style>
</head>
<body>
  <div id="box1"></div>
  <div id="box2"></div>
  <script>
    var box11 = document.getElementById("box1")
    var box21 = document.getElementById("box2")
    
    if(knock(box21,box11)){
      box1.style.backgroundColor="blue";
    }else{
      box1.style.backgroundColor="grey";
    }
    
    function knock(node1,node2){
      var l1 = node1.offsetLeft;
      var r1 = node1.offsetLeft + node1.offsetWidth;
      var t1 = node1.offsetTop;
      var b1 = node1.offsetTop+node1.offsetHeight;
      var l2 = node2.offsetLeft;
      var r2 = node2.offsetLeft + node2.offsetWidth;
      var t2 = node2.offsetTop;
      var b2 = node2.offsetTop+node2.offsetHeight;
      if(l2>r1||r2<l1||t2>b1||b2<t1){
        return false;
      }else{
        return true;
      }
    }
    var oDiv = document.getElementById('box2');
    oDiv.onmousedown = function(ev){
      var e = ev||window.event;
      var offsetX = e.clientX - oDiv.offsetLeft;
      var offsetY = e.clientY - oDiv.offsetTop;
      document.onmousemove = function(ev){
        var e = ev||window.event;
        var l =e.clientX-offsetX;
        var t = e.clientY- offsetY;
        if(knock(box21,box11)){
          box1.style.backgroundColor="blue";
        }else{
          box1.style.backgroundColor="grey";
        }
        if(l<=0){
          l=0;
        }
        if(t<=0){
          t=0;
        }
        var windowWidth =document.documentElement.clientWidth||document.body.clientWidth;
        if(l>=windowWidth-oDiv.offsetWidth){
          l=windowWidth-oDiv.offsetWidth;
        }
        var windowHeight = document.documentElement.clientHeight||document.body.clientHeight
        if(t>=windowHeight-oDiv.offsetHeight){
          t=windowHeight-oDiv.offsetHeight;
        }
        oDiv.style.left = l + "px";
        oDiv.style.top = t + "px";
      }
    }
    document.onmouseup = function(){
      document.onmousemove = null;
    }
  </script>
</body>
</html>

以上为本文的全部内容,希望能为读者的学习提供帮助,欢迎继续支持本站。

作者最新文章