js实现拖拽与碰撞检测


Posted in Javascript onSeptember 18, 2020

本文实例为大家分享了js实现拖拽与碰撞检测的具体代码,供大家参考,具体内容如下

js实现拖拽与碰撞检测

拖拽

原理分析

对于拖拽一个div盒子,首先我们需要将鼠标移动到盒子上,然后按住鼠标左键,移动鼠标到目标位置,再松开鼠标,对于这一过程的分析,

显然需要三个鼠标事件:

  • 按住鼠标:onmousedown
  • 移动鼠标:onmousemove
  • 松开鼠标:onmouseup

实现步骤

1、**鼠标按下时:**我们获取鼠标当前所在的位置距离页面左边界与上边界的距离,分别减去盒子距离页面左边界与上边界的值,这样我们

就得到了鼠标距离盒子左边界与上边界的值;

2、**鼠标移动时:**我们重新获取此时鼠标距离页面左边界与上边界的值,再用它们减去步骤一中得到的鼠标距离盒子左边界与上边界的

值,将得到的值重新赋给盒子,这样盒子就能与鼠标保持相对静止,在页面上移动;

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;
  }

碰撞检测

原理分析

js中碰撞检测在应用于制作一些小游戏,如飞机大战、打砖块、贪吃蛇等,那么如何实现碰撞检测呢?

对于两个矩形方块之间的碰撞,如果直接思考如何书写代码检测它们之间有没有发生接触,这是一个比较难的事情,我们可以换一个思路,

找出它们没有发生碰撞得情况,排除这些情况,那么剩余的情况必然是发生了碰撞。

如下图,检测方块a与b之间是否发生碰撞,我们可以分别获取a与b的上、下边的top值,左右边的left值,那么以下四种情况是没有发生碰撞的:

js实现拖拽与碰撞检测

不会发生碰撞的4种情况:

1、a左>b右
2、a上>b下
3、a右<b左
4、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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
豆瓣网的jquery代码实例
Jun 15 Javascript
基于jquery的无刷新分页技术
Jun 11 Javascript
JavaScript用select实现日期控件
Jul 17 Javascript
javascript入门教程基础篇
Nov 16 Javascript
js css自定义分页效果
Feb 24 Javascript
vue2实现数据请求显示loading图
Nov 28 Javascript
Vue 源码分析之 Observer实现过程
Mar 29 Javascript
vue实现todolist基本功能以及数据存储功能实例详解
Apr 11 Javascript
基于Vue el-autocomplete 实现类似百度搜索框功能
Oct 25 Javascript
Echarts实现单条折线可拖拽效果
Dec 19 Javascript
JavaScript装饰者模式原理与用法实例详解
Mar 09 Javascript
uni-app 自定义底部导航栏的实现
Dec 11 Javascript
详解JavaScript 的执行机制
Sep 18 #Javascript
鸿蒙系统中的 JS 开发框架
Sep 18 #Javascript
React倒计时功能实现代码——解耦通用
Sep 18 #Javascript
浅谈鸿蒙 JavaScript GUI 技术栈
Sep 17 #Javascript
vue项目中播放rtmp视频文件流的方法
Sep 17 #Javascript
逐行分析鸿蒙系统的 JavaScript 框架(推荐)
Sep 17 #Javascript
vue项目实现多语言切换的思路
Sep 17 #Javascript
You might like
在同一窗体中使用PHP来处理多个提交任务
2008/05/08 PHP
用PHP的ob_start() 控制您的浏览器cache
2009/08/03 PHP
php结合表单实现一些简单功能的例子
2011/06/04 PHP
php读取excel文件的简单实例
2013/08/26 PHP
php通过排列组合实现1到9数字相加都等于20的方法
2015/08/03 PHP
PHP类型约束用法示例
2016/09/28 PHP
php实现的简单数据库操作Model类
2016/11/16 PHP
Laravel 实现密码重置功能
2018/02/23 PHP
多个Laravel项目如何共用migrations详解
2018/09/25 PHP
CI框架教程之优化验证码机制详解【验证码辅助函数】
2019/04/16 PHP
获取URL地址中的文件名和参数的javascript代码
2009/09/02 Javascript
js下用eval生成JSON对象
2010/09/17 Javascript
javascript页面渲染速度测试脚本分享
2014/04/15 Javascript
iframe子页面与父页面在同域或不同域下的js通信
2014/05/07 Javascript
jQuery Easyui datagrid/treegrid 清空数据
2016/07/09 Javascript
jQuery Easyui DataGrid点击某个单元格即进入编辑状态焦点移开后保存数据
2016/08/15 Javascript
Ubuntu 16.04 64位中搭建Node.js开发环境教程
2016/10/19 Javascript
探究Vue.js 2.0新增的虚拟DOM
2016/10/20 Javascript
nodejs搭建本地http服务器教程
2017/03/13 NodeJs
Angular2使用jQuery的方法教程
2017/05/28 jQuery
nodejs 最新版安装npm 的使用详解
2018/01/18 NodeJs
详解小程序不同页面之间通讯的解决方案
2018/11/23 Javascript
three.js 利用uv和ThreeBSP制作一个快递柜功能
2020/08/18 Javascript
用Python进行行为驱动开发的入门教程
2015/04/23 Python
python实现矩阵乘法的方法
2015/06/28 Python
浅谈python可视化包Bokeh
2018/02/07 Python
Python基于聚类算法实现密度聚类(DBSCAN)计算【测试可用】
2018/12/26 Python
Python SELENIUM上传文件或图片实现过程
2019/10/28 Python
pymysql模块使用简介与示例
2020/11/17 Python
澳大利亚领先的在线美容商店:Facial Co
2017/10/22 全球购物
英国顶级珠宝品牌之家:John Greed
2018/06/09 全球购物
乡镇群众路线整改落实情况汇报
2014/10/28 职场文书
廉政承诺书2015
2015/04/28 职场文书
Python 解决空列表.append() 输出为None的问题
2021/05/23 Python
用JS写一个发布订阅模式
2021/11/07 Javascript
微信小程序APP的事件绑定以及传递参数时的冒泡和捕获
2022/04/19 Javascript