碰撞检测和拖拽选框

2,854 阅读2分钟

掌握知识点

  • 基础html
  • 基础css
  • 会js写拖拽效果,所举例子基于这个效果上实现

碰撞检测(方形)

思路

  • 碰撞体的右边界大于被碰撞体的左边界

# 碰撞检测和拖拽选框

  • 碰撞体的下边界大于被碰撞体的上边界

  • 碰撞体的左边界小于被碰撞体的右边界

  • 碰撞体的上边界小于被碰撞体的下边界

  • 有上述情况出现了,就表示元素之间碰撞了

实现

  1. 获取,获取两个碰撞体的4条边距离可视区的距离 --方法: getBoundingClientRect()

  2. 判断1,基于上面的思路给出的判断条件:1的左边小于2的右边 并且 1的右边大于2的左边 并且 1的底边大于2的顶边 并且 1的顶边小于2的底边。4个条件同时成立了就表示碰上了

    boxRect1L < boxRect2R && boxRect1B > boxRect2T && boxRect1R > boxRect2L && boxRect1T < boxRect2B
    
  3. 判断2,基于判断1取反

    1. o1L > o2R || o1R < o2L || o1B < o2T || o1T > o2B 
      

碰撞检测(圆形)

思路

  1. 核心:计算两圆心之间的距离

实现

// 检测两个元素,是否重叠(碰撞)
function isContactCircle(el,el2){
     // 两个圆心距离小于两个半径和就碰撞
    let elRect = el.getBoundingClientRect();
     // 元素1圆心坐标
    let elCenter = {
        x: elRect.left + elRect.width/2,
        y: elRect.top + elRect.height/2
    };
    let el2Rect = el2.getBoundingClientRect();
    // 元素2圆心坐标
    let el2Center = {
        x: el2Rect.left + el2Rect.width/2,
        y: el2Rect.top + el2Rect.height/2
    };
    // 斜边的平方(圆心距的平方)
    // let dis2 = (elCenter.x - el2Center.x)*(elCenter.x - el2Center.x) + (elCenter.y - el2Center.y)*(elCenter.y - el2Center.y);
    // console.log(dis2)
    let dis =Math.pow((elCenter.x - el2Center.x),2)+Math.pow((elCenter.y - el2Center.y),2);
    console.log(dis);
    
    //斜边(圆心距)  Math.sqrt() 开平方
    dis = Math.sqrt(dis);
    // 圆心距 <= 半径和       
    return dis <= elRect.width/2 + el2Rect.width/2;

        //  勾股定理:斜边的平方 = 直角边1的平方 + 直角边2的平方
    
    // console.log(elRect.left,elRect.top);//圆左上角的坐标
    // console.log(,elRect.top - elRect.width/2);//圆心坐标
}

拖拽选框

思路

  1. 获取鼠标点下去的起始点就是元素的left top值
  2. 获取鼠标抬起的点与鼠标的起始点的XY的差值就是这个选框元素的宽高了
  3. 元素先加入到文档节点里面去
  4. 注意点1:
    1. 正方向拖动即左上往右下拖动,e.clientX - downX 都是正值
    2. 反方向拖动即右下往左上拖动,e.clientX - downX 都是正值
    3. 所以这里要取绝对值
  5. 注意点2:
    1. 正值的left top 可以直接赋给元素
    2. 负值的left top 要做一个判断,将较小的值赋给元素
    3. 口诀:谁小听谁的

实现:

window.addEventListener('mousedown',function(e){
    //获取鼠标点下去的起始点就是元素的left top值
    var downX = e.clientX;
    var downY = e.clientY;
	//加入元素
    var box = document.createElement('div');
    box.classList.add('box');
    document.body.appendChild(box);
	
    function move(e){
        //获取鼠标抬起的点与鼠标的起始点的XY的差值就是这个选框元素的宽高了
        let disX = Math.abs(e.clientX - downX) ;
        let disY = Math.abs(e.clientY - downY);

        box.style.left = Math.min(downX,e.clientX)  + 'px';
        box.style.top = Math.min(downY,e.clientY)  + 'px';
        box.style.width = disX +'px';
        box.style.height = disY +'px';

    }
    document.addEventListener('mousemove',move)
    document.addEventListener('mouseup',function(){
        document.removeEventListener('mousemove',move);
    },{
        once:true
    })

    e.preventDefault();
})